diff --git a/.cursor/rules/architecture.mdc b/.cursor/rules/architecture.mdc index 28daeac6..3337e5c2 100644 --- a/.cursor/rules/architecture.mdc +++ b/.cursor/rules/architecture.mdc @@ -1,5 +1,5 @@ --- -description: Git Board Flow – entry points, flow, and key paths +description: Copilot – entry points, flow, and key paths alwaysApply: true --- @@ -43,7 +43,7 @@ alwaysApply: true ## CLI-only (not single actions) -- **Copilot**: `giik copilot -p "..."` uses OpenCode build agent via `AiRepository.copilotMessage` in `src/cli.ts`. No workflow single-action equivalent. +- **Do (AI assistant)**: `copilot do -p "..."` uses OpenCode build agent via `AiRepository.copilotMessage` in `src/cli.ts`. No workflow single-action equivalent. ## Concurrency (sequential runs) diff --git a/.cursor/rules/code-conventions.mdc b/.cursor/rules/code-conventions.mdc index dffface3..ba9565dd 100644 --- a/.cursor/rules/code-conventions.mdc +++ b/.cursor/rules/code-conventions.mdc @@ -1,5 +1,5 @@ --- -description: Git Board Flow – coding conventions and where to change things +description: Copilot – coding conventions and where to change things globs: src/**/*.ts alwaysApply: false --- diff --git a/.cursor/rules/commit-messages.mdc b/.cursor/rules/commit-messages.mdc new file mode 100644 index 00000000..5057ad20 --- /dev/null +++ b/.cursor/rules/commit-messages.mdc @@ -0,0 +1,32 @@ +--- +description: Commit message nomenclature (prefix = current branch) +alwaysApply: true +--- + +# Commit messages + +The commit message must use the **current branch name as prefix**, with any `/` replaced by `-`. + +## Format + +``` +: + +[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. diff --git a/.cursor/rules/project-context.mdc b/.cursor/rules/project-context.mdc index 2f24fc75..674df7c1 100644 --- a/.cursor/rules/project-context.mdc +++ b/.cursor/rules/project-context.mdc @@ -1,9 +1,9 @@ --- -description: Git Board Flow – quick read, commands, and where to find more +description: Copilot – quick read, commands, and where to find more alwaysApply: true --- -# Git Board Flow – Project Context +# Copilot – Project Context ## Quick read (for fast understanding) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 11078ce1..bf9b1c7c 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -1,5 +1,5 @@ name: 🐛 Bug Report -description: Report a bug on git-board-flow +description: Report a bug on copilot title: "" labels: ["bug", "bugfix", "priority: high"] body: @@ -68,8 +68,8 @@ body: - type: input attributes: - label: git-board-flow Version - description: What version of git-board-flow is being used? + label: copilot Version + description: What version of copilot is being used? placeholder: "master" validations: required: true diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml index eba09ef6..df7bf8e7 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yml +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -1,5 +1,5 @@ name: ✨ Feature Request -description: Propose an idea or improvement for git-board-flow +description: Propose an idea or improvement for copilot title: "" labels: ["enhancement", "feature", "priority: low"] body: @@ -92,9 +92,9 @@ body: - type: input attributes: - label: Version of git-board-flow + label: Version of copilot description: | - What version of git-board-flow are you using, or does this proposal apply to all versions? + What version of copilot are you using, or does this proposal apply to all versions? placeholder: "master" validations: required: false diff --git a/.github/ISSUE_TEMPLATE/hotfix.yml b/.github/ISSUE_TEMPLATE/hotfix.yml index 08c8f6c9..618ca772 100644 --- a/.github/ISSUE_TEMPLATE/hotfix.yml +++ b/.github/ISSUE_TEMPLATE/hotfix.yml @@ -1,6 +1,6 @@ name: 🔥 Hotfix Issue -description: Request a new hotfix for git-board-flow (only team members) +description: Request a new hotfix for copilot (only team members) title: "" labels: [ "hotfix", "branched", "priority: high" ] body: @@ -8,7 +8,7 @@ body: attributes: value: | ### ⚠️ Disclaimer - > **Only members of the git-board-flow team can create hotfix issues.** + > **Only members of the copilot team can create hotfix issues.** > Any hotfix issue created by someone outside the team will be closed automatically. --- diff --git a/.github/ISSUE_TEMPLATE/release.yml b/.github/ISSUE_TEMPLATE/release.yml index 465de4e8..da4884d1 100644 --- a/.github/ISSUE_TEMPLATE/release.yml +++ b/.github/ISSUE_TEMPLATE/release.yml @@ -1,5 +1,5 @@ name: 🚀 Release Issue -description: Request a new release for giik (only team members) +description: Request a new release for copilot (only team members) title: "" labels: ["release", "branched", "priority: medium"] body: @@ -7,7 +7,7 @@ body: attributes: value: | ### ⚠️ Disclaimer - > **Only members of the giik team can create release issues.** + > **Only members of the copilot team can create release issues.** > Any release issue created by someone outside the team will be closed automatically. --- diff --git a/.github/workflows/ci_check.yml b/.github/workflows/ci_check.yml new file mode 100644 index 00000000..c5c0a074 --- /dev/null +++ b/.github/workflows/ci_check.yml @@ -0,0 +1,35 @@ +name: CI Check + +on: + pull_request: + types: [opened, synchronize] + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number }} + cancel-in-progress: true + +jobs: + ci-check: + name: CI Check + runs-on: ubuntu-latest + permissions: + contents: read + steps: + - uses: actions/checkout@v4 + + - name: Set up Node.js 20 + uses: actions/setup-node@v4 + with: + node-version: '20.x' + + - name: Install dependencies + run: npm ci + + - name: Build + run: npm run build + + - name: Run tests + run: npm test + + - name: Lint + run: npm run lint diff --git a/.github/workflows/gbf_commit.yml b/.github/workflows/copilot_commit.yml similarity index 74% rename from .github/workflows/gbf_commit.yml rename to .github/workflows/copilot_commit.yml index 2641c96c..7a2a691c 100644 --- a/.github/workflows/gbf_commit.yml +++ b/.github/workflows/copilot_commit.yml @@ -1,4 +1,4 @@ -name: Git Board Flow - Commit +name: Copilot - Commit on: push: @@ -8,8 +8,8 @@ on: - '!develop' jobs: - git-board-commits: - name: Git Board - Commit + copilot-commits: + name: Copilot - Commit runs-on: ubuntu-latest steps: - name: Checkout Repository @@ -18,6 +18,6 @@ jobs: - uses: ./ with: debug: ${{ vars.DEBUG }} - project-ids: 2 + project-ids: ${{ vars.PROJECT_IDS }} opencode-model: ${{ vars.OPENCODE_MODEL }} token: ${{ secrets.PAT }} diff --git a/.github/workflows/gbf_issue.yml b/.github/workflows/copilot_issue.yml similarity index 77% rename from .github/workflows/gbf_issue.yml rename to .github/workflows/copilot_issue.yml index 25bc8088..aff13994 100644 --- a/.github/workflows/gbf_issue.yml +++ b/.github/workflows/copilot_issue.yml @@ -1,12 +1,12 @@ -name: Git Board Flow - Issue +name: Copilot - Issue on: issues: types: [opened, reopened, edited, labeled, unlabeled, assigned, unassigned] jobs: - git-board-issues: - name: Git Board - Issue + copilot-issues: + name: Copilot - Issue runs-on: ubuntu-latest steps: - name: Checkout Repository @@ -17,5 +17,5 @@ jobs: ai-ignore-files: build/* debug: ${{ vars.DEBUG }} opencode-model: ${{ vars.OPENCODE_MODEL }} - project-ids: 2 + project-ids: ${{ vars.PROJECT_IDS }} token: ${{ secrets.PAT }} diff --git a/.github/workflows/gbf_issue_comment.yml b/.github/workflows/copilot_issue_comment.yml similarity index 73% rename from .github/workflows/gbf_issue_comment.yml rename to .github/workflows/copilot_issue_comment.yml index 88f22f7e..2b3c8f46 100644 --- a/.github/workflows/gbf_issue_comment.yml +++ b/.github/workflows/copilot_issue_comment.yml @@ -1,12 +1,12 @@ -name: Git Board Flow - Issue Comment +name: Copilot - Issue Comment on: issue_comment: types: [created, edited] jobs: - git-board-issues: - name: Git Board - Issue Comment + copilot-issues: + name: Copilot - Issue Comment runs-on: ubuntu-latest steps: - name: Checkout Repository @@ -17,5 +17,5 @@ jobs: ai-ignore-files: build/* debug: ${{ vars.DEBUG }} opencode-model: ${{ vars.OPENCODE_MODEL }} - project-ids: 2 + project-ids: ${{ vars.PROJECT_IDS }} token: ${{ secrets.PAT }} diff --git a/.github/workflows/gbf_pull_request.yml b/.github/workflows/copilot_pull_request.yml similarity index 76% rename from .github/workflows/gbf_pull_request.yml rename to .github/workflows/copilot_pull_request.yml index 35968cac..a02ef486 100644 --- a/.github/workflows/gbf_pull_request.yml +++ b/.github/workflows/copilot_pull_request.yml @@ -1,12 +1,12 @@ -name: Git Board Flow - Pull Request +name: Copilot - Pull Request on: pull_request: types: [opened, reopened, edited, labeled, unlabeled, closed, assigned, unassigned, synchronize] jobs: - git-board-pull-requests: - name: Git Board - Pull Request + copilot-pull-requests: + name: Copilot - Pull Request runs-on: ubuntu-latest steps: - name: Checkout Repository @@ -17,5 +17,5 @@ jobs: ai-ignore-files: build/* debug: ${{ vars.DEBUG }} opencode-model: ${{ vars.OPENCODE_MODEL }} - project-ids: 2 + project-ids: ${{ vars.PROJECT_IDS }} token: ${{ secrets.PAT }} diff --git a/.github/workflows/gbf_pull_request_review_comment.yml b/.github/workflows/copilot_pull_request_comment.yml similarity index 69% rename from .github/workflows/gbf_pull_request_review_comment.yml rename to .github/workflows/copilot_pull_request_comment.yml index 08fa9e4f..99246ff9 100644 --- a/.github/workflows/gbf_pull_request_review_comment.yml +++ b/.github/workflows/copilot_pull_request_comment.yml @@ -1,12 +1,12 @@ -name: Git Board Flow - Pull Request Review Comment +name: Copilot - Pull Request Comment on: pull_request_review_comment: types: [created, edited] jobs: - git-board-pull-requests: - name: Git Board - Pull Request Review Comment + copilot-pull-requests: + name: Copilot - Pull Request Comment runs-on: ubuntu-latest steps: - name: Checkout Repository @@ -17,6 +17,6 @@ jobs: ai-ignore-files: build/* debug: ${{ vars.DEBUG }} opencode-model: ${{ vars.OPENCODE_MODEL }} - project-ids: 2 + project-ids: ${{ vars.PROJECT_IDS }} token: ${{ secrets.PAT }} - \ No newline at end of file + diff --git a/.github/workflows/hotfix_workflow.yml b/.github/workflows/hotfix_workflow.yml index 5a414176..feac75e9 100644 --- a/.github/workflows/hotfix_workflow.yml +++ b/.github/workflows/hotfix_workflow.yml @@ -118,7 +118,7 @@ jobs: - name: Checkout Repository uses: actions/checkout@v4 - - name: Git Board Flow - Create Tag + - name: Copilot - Create Tag uses: ./ if: ${{ success() }} with: @@ -128,7 +128,7 @@ jobs: single-action-version: '${{ github.event.inputs.version }}' token: ${{ secrets.PAT }} - - name: Git Board Flow - Create Release + - name: Copilot - Create Release uses: ./ if: ${{ success() }} with: @@ -140,7 +140,7 @@ jobs: single-action-changelog: '${{ github.event.inputs.changelog }}' token: ${{ secrets.PAT }} - - name: Git Board Flow - Publish Github Action Version + - name: Copilot - Publish Github Action Version uses: ./ if: ${{ success() }} with: @@ -150,7 +150,7 @@ jobs: single-action-version: '${{ github.event.inputs.version }}' token: ${{ secrets.PAT }} - - name: Git Board Flow - Deploy success notification + - name: Copilot - Deploy success notification uses: ./ if: ${{ success() }} with: diff --git a/.github/workflows/prepare_files.yml b/.github/workflows/prepare_files.yml deleted file mode 100644 index 505f118d..00000000 --- a/.github/workflows/prepare_files.yml +++ /dev/null @@ -1,48 +0,0 @@ -name: Prepare Files - -on: - push: - branches-ignore: - - master - - 'release/*' - - 'hotfix/*' - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -jobs: - prepare-files: - name: Update compiled files - runs-on: ubuntu-latest - permissions: - contents: write - steps: - - uses: actions/checkout@v4 - - - name: Set up Node.js 20 - uses: actions/setup-node@v4 - with: - node-version: '20.x' - - - name: Install dependencies - run: npm ci - - - name: Build - run: npm run build - - - name: Run tests - run: npm test - - - name: Lint - run: npm run lint - - - name: Commit updated build directory - uses: EndBug/add-and-commit@v9 - with: - add: './build/ --force' - committer_name: GitHub Actions - committer_email: actions@github.com - default_author: user_info - message: 'gh-action: updated compiled files' - push: true diff --git a/.github/workflows/release_workflow.yml b/.github/workflows/release_workflow.yml index f6a02239..8a4bdb2d 100644 --- a/.github/workflows/release_workflow.yml +++ b/.github/workflows/release_workflow.yml @@ -118,7 +118,7 @@ jobs: - name: Checkout Repository uses: actions/checkout@v4 - - name: Git Board Flow - Create Tag + - name: Copilot - Create Tag uses: ./ if: ${{ success() }} with: @@ -128,7 +128,7 @@ jobs: single-action-version: '${{ github.event.inputs.version }}' token: ${{ secrets.PAT }} - - name: Git Board Flow - Create Release + - name: Copilot - Create Release uses: ./ if: ${{ success() }} with: @@ -140,7 +140,7 @@ jobs: single-action-changelog: '${{ github.event.inputs.changelog }}' token: ${{ secrets.PAT }} - - name: Git Board Flow - Publish Github Action Version + - name: Copilot - Publish Github Action Version uses: ./ if: ${{ success() }} with: @@ -150,7 +150,7 @@ jobs: single-action-version: '${{ github.event.inputs.version }}' token: ${{ secrets.PAT }} - - name: Git Board Flow - Deploy success notification + - name: Copilot - Deploy success notification uses: ./ if: ${{ success() }} with: diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2ebd5a2f..dd3377ce 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,6 +1,6 @@ -# Contributing to Git Board Flow +# Contributing to Copilot -Thank you for your interest in contributing to Git Board Flow. This document provides guidelines for setting up the project and submitting changes. +Thank you for your interest in contributing to Copilot. This document provides guidelines for setting up the project and submitting changes. ## Development Setup @@ -61,9 +61,16 @@ npm run build ## Documentation - Update the relevant docs in `docs/` when changing behavior or adding features. -- For user-facing changes, update `README.md` and the docs at [docs.page/landamessenger/git-board-flow](https://docs.page/landamessenger/git-board-flow). -- The project uses [Mintlify](https://mintlify.com/) (docs.page) for docs; see `docs.json` for sidebar structure. -- Use Mintlify components for a consistent, readable UI: **Card**, **Card** inside **Columns**, **Tabs**, **Accordion** / **AccordionGroup**, **Steps**, **Info** / **Warning** / **Tip** / **Note**. See [Mintlify Components](https://mintlify.com/docs/components). +- For user-facing changes, update `README.md` and the docs at [docs.page/vypdev/copilot](https://docs.page/vypdev/copilot). +- The project uses [docs.page](https://docs.page/) (invertase) for publishing; see `docs.json` for sidebar structure. +- Use only **docs.page components** so the site builds without errors: **Card**, **CardGroup** (for multiple cards in a row; use `cols={2}` or `cols={3}`), **Callouts** (**Info**, **Warning**, **Error**, **Success** only — do not use Note or Tip), **Tabs**, **Accordion**, **Steps**, **Code Group**, etc. Do **not** use Mintlify-only components such as **Columns** (use **CardGroup** instead). See [docs.page Components](https://use.docs.page/components). + +## Git hooks + +Hooks are **installed when you run `npm install`** (postinstall). To reinstall: `node scripts/install-git-hooks.cjs`. Works on Windows, macOS, and Linux. On **Windows**, use [Git for Windows](https://git-scm.com/download/win) so hooks run with Bash (the pre-commit launcher is a shell script). + +- **prepare-commit-msg** — Adds the current branch name as prefix to the commit message (with `/` replaced by `-`), e.g. `feature-292-github-action-rename: add concurrency to CI`. +- **pre-commit** — Before each commit, runs `npm run build`, `npm test`, and `npm run lint`. The commit is aborted if any of these fail. ## Submitting Changes @@ -71,8 +78,8 @@ npm run build 2. Make your changes, following the conventions above. 3. Ensure tests pass and lint is clean. 4. Submit a pull request with a clear description of the changes. -5. Link the PR to an issue if applicable (Git Board Flow will help with that!). +5. Link the PR to an issue if applicable (Copilot will help with that!). ## Questions? -Open an issue on [GitHub](https://github.com/landamessenger/git-board-flow) or check the [Support](https://docs.page/landamessenger/git-board-flow/support) page in the documentation. +Open an issue on [GitHub](https://github.com/vypdev/copilot) or check the [Support](https://docs.page/vypdev/copilot/support) page in the documentation. diff --git a/LICENSE b/LICENSE index 8c7bd996..31822ab5 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2024 Landa Messenger +Copyright (c) 2026 vypdev Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index b832b6f2..dbc6d540 100644 --- a/README.md +++ b/README.md @@ -1,229 +1,53 @@ -# Git Board Flow: Automated Branch and Project Management GitHub Action +# Copilot — GitHub with super powers -**Git Board Flow** is a GitHub Action that automates issue, branch, and project management using the Git-Flow methodology. It creates and links branches to issues, monitors commits and pull requests, and integrates with GitHub Projects. +**Copilot** is a GitHub Action for task management using Git-Flow: it links issues, branches, and pull requests to GitHub Projects, automates branch creation from labels, and keeps boards and progress in sync. Think of it as bringing Atlassian-style integration (boards, tasks, branches) to GitHub. -**Full documentation:** [docs.page/landamessenger/git-board-flow](https://docs.page/landamessenger/git-board-flow) — setup, configuration, single actions, and AI (OpenCode). +Full documentation: **[docs.page/vypdev/copilot](https://docs.page/vypdev/copilot)** --- -## AI features (OpenCode) +## Documentation index -All AI features use **OpenCode** (75+ LLM providers: OpenAI, Anthropic, Gemini, local models, etc.): - -- **Progress detection** — On every push, analyzes branch vs issue and updates the progress label on the issue and on any open PRs for that branch. You can also run it on demand via single action or CLI (`check-progress`). -- **Bugbot (potential problems)** — On every push (or on demand via single action / CLI `detect-potential-problems`), OpenCode analyzes the branch vs base and reports findings as **comments on the issue** and **review comments on open PRs**; it updates or marks them as resolved when findings are fixed. -- **Think / reasoning** — Deep code analysis and change proposals (`think_action`). -- **AI PR description** — Generates or updates pull request descriptions by filling your `.github/pull_request_template.md` from the issue and branch diff. - -You can set `opencode-server-url` and `opencode-model`, or use **`opencode-start-server: true`** so the action starts and stops an OpenCode server in the job (no separate install needed; pass provider API keys as secrets). - -See the [OpenCode (AI)](https://docs.page/landamessenger/git-board-flow/opencode-integration) docs for configuration and [Features & Capabilities](https://docs.page/landamessenger/git-board-flow/features) for the full list of actions. - ---- - -## Key features - -- **Automatic branch creation** — From issue labels (feature, bugfix, hotfix, release, docs, chore); branches are linked to the issue and summarized in a comment. -- **Commit monitoring** — Posts commit summaries on the issue when pushes occur on linked branches; optional commit prefix validation. -- **Pull request linking** — Links PRs to issues, adds them to projects, assigns reviewers, and can generate PR descriptions with AI. -- **GitHub Project integration** — Links issues and PRs to the configured projects (`project-ids`) and moves them to the right columns. -- **Single actions** — Run on-demand actions: check progress, think, create release/tag, deployed marking, and more. -- **Workflow concurrency** — The action waits for previous runs of the **same workflow name** to finish, so you can run workflows sequentially (no cancel). See [Features → Workflow concurrency](https://docs.page/landamessenger/git-board-flow/features#workflow-concurrency-and-sequential-execution). - ---- - -## Quick start - -### Issue workflow - -```yaml -name: Git Board Flow - Issue - -on: - issues: - types: [opened, edited, labeled, unlabeled] - -jobs: - git-board-flow-issues: - name: Git Board Flow - Issue - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: landamessenger/git-board-flow@master - with: - token: ${{ secrets.PAT }} - project-ids: '2,3' - commit-prefix-transforms: 'replace-slash' -``` - -### Pull request workflow - -```yaml -name: Git Board Flow - Pull Request - -on: - pull_request: - types: [opened, edited, labeled, unlabeled] - -concurrency: - group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} - cancel-in-progress: true - -jobs: - git-board-flow-pull-requests: - name: Git Board Flow - Pull Request - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: landamessenger/git-board-flow@master - with: - token: ${{ secrets.PAT }} - project-ids: '2,3' - commit-prefix-transforms: 'replace-slash' -``` - -### Commit (push) workflow - -This workflow runs on every push. It notifies the issue of new commits, updates **size** and **progress** labels on the issue and on any open PRs for that branch (progress requires OpenCode), and can run **Bugbot** to report potential problems as issue and PR comments (OpenCode). No separate "check progress" workflow is needed. - -```yaml -name: Git Board Flow - Commit - -on: - push: - branches: ['**'] - -jobs: - git-board-flow-commits: - name: Git Board Flow - Commit - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: landamessenger/git-board-flow@master - with: - token: ${{ secrets.PAT }} - commit-prefix-transforms: 'replace-slash' - # Optional: for progress labels, add OpenCode config - # opencode-server-url: ${{ secrets.OPENCODE_SERVER_URL }} - # opencode-model: 'anthropic/claude-3-5-sonnet' -``` - -A **fine-grained Personal Access Token (PAT)** is required for branch and project operations. See [Authentication](https://docs.page/landamessenger/git-board-flow/authentication) in the docs. - ---- - -## Testing locally (CLI) - -The same logic as the GitHub Action runs in **CLI mode** via the `giik` command, so you can test workflows locally before pushing. - -### 1. Prerequisites - -- **Node.js 20** (e.g. `nvm use 20`). -- **Git repo** with `origin` pointing to a GitHub repo (e.g. `github.com/owner/repo`). The CLI reads `git config remote.origin.url` to get owner/repo. -- **Personal Access Token** for GitHub (env `PERSONAL_ACCESS_TOKEN` or `-t` / `--token`). -- For **AI features**: a running [OpenCode](https://docs.page/landamessenger/git-board-flow/opencode-integration) server (default `http://localhost:4096`). Optional env: `OPENCODE_SERVER_URL`, `OPENCODE_MODEL`. - -### 2. Build and run - -```bash -nvm use 20 -npm install -npm run build -``` - -Run the CLI from the repo root (same repo that will use the action, or any repo with the same `origin`): - -```bash -# Using the built binary (no global install) -node build/cli/index.js [options] - -# Or, if you install/link the package so that `giik` is on PATH: -giik [options] -``` - -### 3. Commands that mirror the action - -| Command | Description | Example | -|--------|-------------|--------| -| `setup` | Initial setup: labels, issue types, verify access | `node build/cli/index.js setup -t ` | -| `check-progress` | Run progress check on demand (progress is also updated automatically on every push) | `node build/cli/index.js check-progress -i 123 -t ` | -| `detect-potential-problems` | Bugbot: detect potential problems, report on issue and PR (OpenCode) | `node build/cli/index.js detect-potential-problems -i 123 -t ` | -| `recommend-steps` | Recommend implementation steps for an issue (OpenCode Plan) | `node build/cli/index.js recommend-steps -i 123 -t ` | -| `think` | Deep code analysis / reasoning (needs a question) | `node build/cli/index.js think -q "Where is auth validated?" -t ` | -| `copilot` | AI development assistant (analyze/modify code) | `node build/cli/index.js copilot -p "Explain src/cli.ts" -t ` | - -Add `-d` or `--debug` for verbose logs. For OpenCode, use `--opencode-server-url` and `--opencode-model` if you don’t set env vars. - -For a step-by-step guide to testing the OpenCode Plan flows (check-progress, detect-potential-problems, recommend-steps) locally, see [Testing OpenCode Plan Locally](https://docs.page/landamessenger/git-board-flow/testing-opencode-plan-locally). - -### 4. Optional: `.env` in repo root - -You can put secrets in a `.env` file (do not commit it). The CLI loads it via `dotenv`: - -```bash -# .env (do not commit) -PERSONAL_ACCESS_TOKEN=ghp_... -OPENCODE_SERVER_URL=http://localhost:4096 -OPENCODE_MODEL=opencode/kimi-k2.5 -``` - -Then you can run without passing `-t` every time, e.g.: - -```bash -node build/cli/index.js setup -node build/cli/index.js check-progress -i 123 -``` - ---- - -## Code quality (ESLint) - -The project uses **ESLint** with **typescript-eslint** (similar to Detekt/Ktlint for Kotlin) for TypeScript linting: - -- `npm run lint` — runs ESLint on `src/`. Reports unused variables, `any` usage, and recommended rules. -- `npm run lint:fix` — auto-fixes what can be fixed (e.g. `prefer-const`, useless escapes). - -Config: `eslint.config.mjs` (flat config). Test files (`*.test.ts`, `__tests__/**`) have relaxed rules for mocks. Fix remaining issues over time so CI can run `npm run lint` without failures. +| Section | Description | +|--------|-------------| +| [How to use](https://docs.page/vypdev/copilot/how-to-use) | Step-by-step setup: PAT, `copilot setup`, workflows | +| [Features & capabilities](https://docs.page/vypdev/copilot/features) | Workflow triggers, single actions, AI (OpenCode), concurrency | +| [Authentication](https://docs.page/vypdev/copilot/authentication) | PAT setup, permissions, token best practices | +| [Configuration](https://docs.page/vypdev/copilot/configuration) | All inputs: branches, labels, projects, images, etc. | +| [OpenCode (AI)](https://docs.page/vypdev/copilot/opencode-integration) | Progress, Bugbot, think, AI PR description | +| [Testing OpenCode locally](https://docs.page/vypdev/copilot/testing-opencode-plan-locally) | Run check-progress, detect-potential-problems, recommend-steps via CLI | +| [Single actions](https://docs.page/vypdev/copilot/single-actions) | On-demand: check progress, think, create release/tag, deployed | +| [Issues](https://docs.page/vypdev/copilot/issues) | Issue configuration and types (feature, bugfix, hotfix, release, docs, chore) | +| [Pull requests](https://docs.page/vypdev/copilot/pull-requests) | PR configuration and AI description | +| [Troubleshooting](https://docs.page/vypdev/copilot/troubleshooting) | Common issues and solutions | +| [Support](https://docs.page/vypdev/copilot/support) | How to get help | --- -## Commit prefix transforms - -The `commit-prefix-transforms` input defines how branch names are turned into commit prefixes. You can chain several transforms (comma-separated). - -| Transform | Example | -|-----------|---------| -| `replace-slash` | `feature/user-auth` → `feature-user-auth` | -| `replace-all` | Replace special chars with `-` | -| `lowercase`, `uppercase` | Case conversion | -| `kebab-case`, `snake-case`, `camel-case` | Naming style | -| `trim`, `clean-dashes`, `clean-underscores` | Cleanup | -| `remove-numbers`, `remove-special`, `remove-spaces` | Character removal | - -Example: +## Getting started -```yaml -commit-prefix-transforms: "replace-all,lowercase,clean-dashes" -# Feature/User_Auth! → feature-user-auth -``` - -Default is `replace-slash`. Full list and details: [Configuration](https://docs.page/landamessenger/git-board-flow/configuration). +1. **Create a PAT** and store it as a repo secret (e.g. `PAT`). See [Authentication](https://docs.page/vypdev/copilot/authentication). +2. **Use the action** from the marketplace so versions are stable: + ```yaml + uses: vypdev/copilot@v1 + ``` +3. **Add workflows** — Copy the files from `setup/workflows/` into your `.github/workflows/`, or run **`copilot setup`** from your repo root (with `PERSONAL_ACCESS_TOKEN` in `.env`). See [How to use](https://docs.page/vypdev/copilot/how-to-use). --- -## Why Git Board Flow - -- **Git-Flow aligned** — Feature, bugfix, hotfix, release, docs, and chore branches with consistent naming. -- **Visibility** — Issues, branches, and PRs stay linked and reflected on project boards. -- **Less manual work** — Branch creation, linking, assignees, reviewers, and comments are automated. -- **Fast** — Runs on Ubuntu and is designed to complete quickly. +## What it does ---- +- **Issues** — Branch creation from labels (feature, bugfix, hotfix, release, docs, chore), project linking, assignees, size/progress labels; optional Bugbot (AI) on the issue. +- **Pull requests** — Link PRs to issues, update project columns, assign reviewers; optional AI-generated PR description. +- **Push (commits)** — Notify the issue, update size/progress; optional Bugbot and prefix checks. +- **Projects** — Link issues and PRs to boards and move them to the right columns. +- **Single actions** — On-demand: check progress, think, create release/tag, mark deployed, etc. +- **Concurrency** — Waits for previous runs of the same workflow so runs can be sequential. See [Features → Workflow concurrency](https://docs.page/vypdev/copilot/features#workflow-concurrency-and-sequential-execution). -Transform your GitHub workflow with **Git Board Flow**. For full feature list, single actions, and configuration, see the [documentation](https://docs.page/landamessenger/git-board-flow). +AI features (progress, Bugbot, think, AI PR description) use **OpenCode**; see [OpenCode (AI)](https://docs.page/vypdev/copilot/opencode-integration). You can also run progress and Bugbot locally via the **CLI** — [Testing OpenCode locally](https://docs.page/vypdev/copilot/testing-opencode-plan-locally) and [Single actions → Workflow & CLI](https://docs.page/vypdev/copilot/single-actions/workflow-and-cli). --- ## Contributing -Contributions are welcome. See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup, conventions, and how to submit changes. +See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup, conventions, and how to submit changes. diff --git a/action.yml b/action.yml index 84461b76..a74dd714 100644 --- a/action.yml +++ b/action.yml @@ -1,6 +1,6 @@ -name: "Git Board Flow" +name: "Copilot" description: "Automates branch management, GitHub project linking, and issue/PR tracking with Git-Flow methodology." -author: "Landa Messenger" +author: "Efra Espada" inputs: debug: description: "Enable debug mode." diff --git a/build/cli/index.js b/build/cli/index.js index be3473d4..6a9a10b5 100755 --- a/build/cli/index.js +++ b/build/cli/index.js @@ -46973,6 +46973,7 @@ const dotenv = __importStar(__nccwpck_require__(2437)); const local_action_1 = __nccwpck_require__(7002); const issue_repository_1 = __nccwpck_require__(57); const constants_1 = __nccwpck_require__(8593); +const logger_1 = __nccwpck_require__(8836); const ai_1 = __nccwpck_require__(4470); const ai_repository_1 = __nccwpck_require__(8307); // Load environment variables from .env file @@ -47022,8 +47023,8 @@ program .action(async (options) => { const gitInfo = getGitInfo(); if ('error' in gitInfo) { - console.log(gitInfo.error); - return; + (0, logger_1.logError)(gitInfo.error); + process.exit(1); } // Helper function to clean CLI arguments that may have '=' prefix const cleanArg = (value) => { @@ -47088,18 +47089,17 @@ program `Starting deep code analysis for ${gitInfo.owner}/${gitInfo.repo}/${branch}...`, `Question: ${question.substring(0, 100)}${question.length > 100 ? '...' : ''}`, ]; - // logInfo(JSON.stringify(params, null, 2)); (0, local_action_1.runLocalAction)(params); }); /** - * Copilot - AI development assistant using OpenCode "build" agent. + * Do - AI development assistant using OpenCode "build" agent. * When the OpenCode server is run locally from your repo (e.g. opencode serve), the build agent * can read and write files; changes are applied in the server workspace. */ program - .command('copilot') + .command('do') .description(`${constants_1.TITLE} - AI development assistant (OpenCode build agent; can edit files when run locally)`) - .option('-p, --prompt ', 'Prompt or question for the copilot (required)', '') + .option('-p, --prompt ', 'Prompt or question (required)', '') .option('-d, --debug', 'Debug mode', false) .option('--opencode-server-url ', 'OpenCode server URL', process.env.OPENCODE_SERVER_URL || 'http://127.0.0.1:4096') .option('--opencode-model ', 'OpenCode model', process.env.OPENCODE_MODEL) @@ -47107,8 +47107,8 @@ program .action(async (options) => { const gitInfo = getGitInfo(); if ('error' in gitInfo) { - console.log(gitInfo.error); - return; + (0, logger_1.logError)(gitInfo.error); + process.exit(1); } // Helper function to clean CLI arguments that may have '=' prefix const cleanArg = (value) => { @@ -47139,7 +47139,7 @@ program const aiRepository = new ai_repository_1.AiRepository(); const result = await aiRepository.copilotMessage(ai, prompt); if (!result) { - console.error('❌ Copilot request failed (check OpenCode server and model).'); + console.error('❌ Request failed (check OpenCode server and model).'); process.exit(1); } const { text, sessionId } = result; @@ -47149,7 +47149,7 @@ program return; } console.log('\n' + '='.repeat(80)); - console.log('🤖 COPILOT RESPONSE (OpenCode build agent)'); + console.log('🤖 RESPONSE (OpenCode build agent)'); console.log('='.repeat(80)); console.log(`\n${text || '(No text response)'}\n`); const diff = await (0, ai_repository_1.getSessionDiff)(serverUrl, sessionId); @@ -47166,7 +47166,7 @@ program } catch (error) { const err = error instanceof Error ? error : new Error(String(error)); - console.error('❌ Error executing copilot:', err.message || error); + console.error('❌ Error executing do:', err.message || error); if (options.debug) { console.error(error); } @@ -47188,8 +47188,8 @@ program .action(async (options) => { const gitInfo = getGitInfo(); if ('error' in gitInfo) { - console.log(gitInfo.error); - return; + (0, logger_1.logError)(gitInfo.error); + process.exit(1); } // Helper function to clean CLI arguments that may have '=' prefix const cleanArg = (value) => { @@ -47263,8 +47263,8 @@ program .action(async (options) => { const gitInfo = getGitInfo(); if ('error' in gitInfo) { - console.log(gitInfo.error); - return; + (0, logger_1.logError)(gitInfo.error); + process.exit(1); } const cleanArg = (v) => (v != null ? (String(v).startsWith('=') ? String(v).substring(1) : String(v)) : ''); const issueNumber = cleanArg(options.issue); @@ -47303,8 +47303,8 @@ program .action(async (options) => { const gitInfo = getGitInfo(); if ('error' in gitInfo) { - console.log(gitInfo.error); - return; + (0, logger_1.logError)(gitInfo.error); + process.exit(1); } const cleanArg = (v) => (v != null ? (String(v).startsWith('=') ? String(v).substring(1) : String(v)) : ''); const issueNumber = cleanArg(options.issue); @@ -47342,6 +47342,16 @@ program process.exit(1); } }); +/** Returns true if cwd is inside a git repository (work tree). */ +function isInsideGitRepo(cwd) { + try { + (0, child_process_1.execSync)('git rev-parse --is-inside-work-tree', { cwd, stdio: 'pipe' }); + return true; + } + catch { + return false; + } +} /** * Run the initial setup to configure labels, issue types, and verify access. */ @@ -47351,11 +47361,21 @@ program .option('-d, --debug', 'Debug mode', false) .option('-t, --token ', 'Personal access token', process.env.PERSONAL_ACCESS_TOKEN) .action(async (options) => { + const cwd = process.cwd(); + (0, logger_1.logInfo)('🔍 Checking we are inside a git repository...'); + if (!isInsideGitRepo(cwd)) { + (0, logger_1.logError)('❌ Not a git repository. Run "copilot setup" from the root of a git repo.'); + process.exit(1); + } + (0, logger_1.logInfo)('✅ Git repository detected.'); + (0, logger_1.logInfo)('🔗 Resolving repository (owner/repo)...'); const gitInfo = getGitInfo(); if ('error' in gitInfo) { - console.log(gitInfo.error); - return; + (0, logger_1.logError)(gitInfo.error); + process.exit(1); } + (0, logger_1.logInfo)(`📦 Repository: ${gitInfo.owner}/${gitInfo.repo}`); + (0, logger_1.logInfo)('⚙️ Running initial setup (labels, issue types, access)...'); const params = { [constants_1.INPUT_KEYS.DEBUG]: options.debug.toString(), [constants_1.INPUT_KEYS.SINGLE_ACTION]: constants_1.ACTIONS.INITIAL_SETUP, @@ -49131,7 +49151,7 @@ async function opencodeMessageWithAgentRaw(baseUrl, options) { (0, logger_1.logDebugInfo)(`OpenCode message body: agent=${options.agent}, model=${options.providerID}/${options.modelID}, parts[0].text length=${options.promptText.length}`); const base = ensureNoTrailingSlash(baseUrl); const signal = createTimeoutSignal(constants_1.OPENCODE_REQUEST_TIMEOUT_MS); - const sessionBody = { title: 'gbf' }; + const sessionBody = { title: 'copilot' }; (0, logger_1.logDebugInfo)(`OpenCode session create body: ${JSON.stringify(sessionBody)}`); const createRes = await fetch(`${base}/session`, { method: 'POST', @@ -49732,7 +49752,7 @@ This PR merges **${head}** into **${base}**. repo: repository, pull_number: pullRequest.number, body: prBody + '\n' + commitMessages.map(msg => `- ${msg}`).join('\n') + - '\n\nThis PR was automatically created by [`git-board-flow`](https://github.com/landamessenger/git-board-flow).' + '\n\nThis PR was automatically created by [`copilot`](https://github.com/vypdev/copilot).' }); const iteration = 10; if (timeout > iteration) { @@ -52048,7 +52068,7 @@ class ContentInterface { }; } get _id() { - return `git-board-flow-${this.id}`; + return `copilot-${this.id}`; } get startPattern() { if (this.visibleContent) { @@ -52249,6 +52269,7 @@ Object.defineProperty(exports, "__esModule", ({ value: true })); exports.CheckProgressUseCase = void 0; const result_1 = __nccwpck_require__(7305); const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); const issue_repository_1 = __nccwpck_require__(57); const branch_repository_1 = __nccwpck_require__(7701); const pull_request_repository_1 = __nccwpck_require__(634); @@ -52272,7 +52293,7 @@ class CheckProgressUseCase { this.aiRepository = new ai_repository_1.AiRepository(); } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const results = []; try { // Check if AI configuration is available @@ -52526,13 +52547,14 @@ const result_1 = __nccwpck_require__(7305); const project_repository_1 = __nccwpck_require__(7917); const constants_1 = __nccwpck_require__(8593); const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); class CreateReleaseUseCase { constructor() { this.taskId = 'CreateReleaseUseCase'; this.projectRepository = new project_repository_1.ProjectRepository(); } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const result = []; if (param.singleAction.version.length === 0) { (0, logger_1.logError)(`Version is not set.`); @@ -52620,13 +52642,14 @@ const result_1 = __nccwpck_require__(7305); const project_repository_1 = __nccwpck_require__(7917); const constants_1 = __nccwpck_require__(8593); const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); class CreateTagUseCase { constructor() { this.taskId = 'CreateTagUseCase'; this.projectRepository = new project_repository_1.ProjectRepository(); } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const result = []; if (param.singleAction.version.length === 0) { (0, logger_1.logError)(`Version is not set.`); @@ -52704,6 +52727,7 @@ const result_1 = __nccwpck_require__(7305); const branch_repository_1 = __nccwpck_require__(7701); const issue_repository_1 = __nccwpck_require__(57); const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); class DeployedActionUseCase { constructor() { this.taskId = 'DeployedActionUseCase'; @@ -52711,7 +52735,7 @@ class DeployedActionUseCase { this.branchRepository = new branch_repository_1.BranchRepository(); } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const result = []; try { if (!param.labels.isDeploy) { @@ -52838,16 +52862,23 @@ const issue_repository_1 = __nccwpck_require__(57); const project_repository_1 = __nccwpck_require__(7917); const result_1 = __nccwpck_require__(7305); const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); +const setup_files_1 = __nccwpck_require__(1666); class InitialSetupUseCase { constructor() { this.taskId = 'InitialSetupUseCase'; } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const results = []; const steps = []; const errors = []; try { + // 0. Setup files (.github/workflows, .github/ISSUE_TEMPLATE, pull_request_template.md, .env) + (0, logger_1.logInfo)('📋 Ensuring .github and copying setup files...'); + (0, setup_files_1.ensureGitHubDirs)(process.cwd()); + const filesResult = (0, setup_files_1.copySetupFiles)(process.cwd()); + steps.push(`✅ Setup files: ${filesResult.copied} copied, ${filesResult.skipped} already existed`); // 1. Verificar acceso a GitHub con Personal Access Token (0, logger_1.logInfo)('🔐 Checking GitHub access...'); const githubAccessResult = await this.verifyGitHubAccess(param); @@ -52985,13 +53016,14 @@ const result_1 = __nccwpck_require__(7305); const project_repository_1 = __nccwpck_require__(7917); const constants_1 = __nccwpck_require__(8593); const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); class PublishGithubActionUseCase { constructor() { this.taskId = 'PublishGithubActionUseCase'; this.projectRepository = new project_repository_1.ProjectRepository(); } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const result = []; if (param.singleAction.version.length === 0) { (0, logger_1.logError)(`Version is not set.`); @@ -53059,6 +53091,7 @@ Object.defineProperty(exports, "__esModule", ({ value: true })); exports.RecommendStepsUseCase = void 0; const result_1 = __nccwpck_require__(7305); const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); const issue_repository_1 = __nccwpck_require__(57); const ai_repository_1 = __nccwpck_require__(8307); class RecommendStepsUseCase { @@ -53068,7 +53101,7 @@ class RecommendStepsUseCase { this.aiRepository = new ai_repository_1.AiRepository(); } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const results = []; try { if (!param.ai?.getOpencodeModel() || !param.ai?.getOpencodeServerUrl()) { @@ -53145,6 +53178,7 @@ Object.defineProperty(exports, "__esModule", ({ value: true })); exports.CommitUseCase = void 0; const result_1 = __nccwpck_require__(7305); const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); const check_progress_use_case_1 = __nccwpck_require__(7744); const notify_new_commit_on_issue_use_case_1 = __nccwpck_require__(8020); const check_changes_issue_size_use_case_1 = __nccwpck_require__(5863); @@ -53154,7 +53188,7 @@ class CommitUseCase { this.taskId = 'CommitUseCase'; } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const results = []; try { if (param.commit.commits.length === 0) { @@ -53197,6 +53231,7 @@ exports.CommitUseCase = CommitUseCase; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.IssueCommentUseCase = void 0; const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); const think_use_case_1 = __nccwpck_require__(3841); const check_issue_comment_language_use_case_1 = __nccwpck_require__(465); class IssueCommentUseCase { @@ -53204,7 +53239,7 @@ class IssueCommentUseCase { this.taskId = 'IssueCommentUseCase'; } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const results = []; results.push(...await new check_issue_comment_language_use_case_1.CheckIssueCommentLanguageUseCase().invoke(param)); results.push(...await new think_use_case_1.ThinkUseCase().invoke(param)); @@ -53224,6 +53259,7 @@ exports.IssueCommentUseCase = IssueCommentUseCase; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.IssueUseCase = void 0; const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); const check_permissions_use_case_1 = __nccwpck_require__(8749); const update_title_use_case_1 = __nccwpck_require__(5107); const assign_members_to_issue_use_case_1 = __nccwpck_require__(3115); @@ -53241,7 +53277,7 @@ class IssueUseCase { this.taskId = 'IssueUseCase'; } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const results = []; const permissionResult = await new check_permissions_use_case_1.CheckPermissionsUseCase().invoke(param); const lastAction = permissionResult[permissionResult.length - 1]; @@ -53310,13 +53346,14 @@ exports.IssueUseCase = IssueUseCase; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.PullRequestReviewCommentUseCase = void 0; const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); const check_pull_request_comment_language_use_case_1 = __nccwpck_require__(7112); class PullRequestReviewCommentUseCase { constructor() { this.taskId = 'PullRequestReviewCommentUseCase'; } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const results = []; results.push(...await new check_pull_request_comment_language_use_case_1.CheckPullRequestCommentLanguageUseCase().invoke(param)); return results; @@ -53336,6 +53373,7 @@ Object.defineProperty(exports, "__esModule", ({ value: true })); exports.PullRequestUseCase = void 0; const result_1 = __nccwpck_require__(7305); const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); const update_title_use_case_1 = __nccwpck_require__(5107); const assign_members_to_issue_use_case_1 = __nccwpck_require__(3115); const assign_reviewers_to_issue_use_case_1 = __nccwpck_require__(6275); @@ -53350,7 +53388,7 @@ class PullRequestUseCase { this.taskId = 'PullRequestUseCase'; } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const results = []; try { (0, logger_1.logDebugInfo)(`PR action ${param.pullRequest.action}`); @@ -53440,6 +53478,7 @@ Object.defineProperty(exports, "__esModule", ({ value: true })); exports.SingleActionUseCase = void 0; const result_1 = __nccwpck_require__(7305); const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); const deployed_action_use_case_1 = __nccwpck_require__(8293); const publish_github_action_use_case_1 = __nccwpck_require__(9029); const create_release_use_case_1 = __nccwpck_require__(2430); @@ -53454,7 +53493,7 @@ class SingleActionUseCase { this.taskId = 'SingleActionUseCase'; } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const results = []; try { if (!param.singleAction.validSingleAction) { @@ -54141,6 +54180,7 @@ const issue_repository_1 = __nccwpck_require__(57); const project_repository_1 = __nccwpck_require__(7917); const pull_request_repository_1 = __nccwpck_require__(634); const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); class CheckChangesIssueSizeUseCase { constructor() { this.taskId = 'CheckChangesIssueSizeUseCase'; @@ -54150,7 +54190,7 @@ class CheckChangesIssueSizeUseCase { this.pullRequestRepository = new pull_request_repository_1.PullRequestRepository(); } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const result = []; try { const baseBranch = param.currentConfiguration.parentBranch ?? @@ -54236,6 +54276,7 @@ const result_1 = __nccwpck_require__(7305); const ai_repository_1 = __nccwpck_require__(8307); const constants_1 = __nccwpck_require__(8593); const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); const build_bugbot_prompt_1 = __nccwpck_require__(6339); const deduplicate_findings_1 = __nccwpck_require__(7384); const file_ignore_1 = __nccwpck_require__(3770); @@ -54253,7 +54294,7 @@ class DetectPotentialProblemsUseCase { this.aiRepository = new ai_repository_1.AiRepository(); } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const results = []; try { if (!param.ai?.getOpencodeModel() || !param.ai?.getOpencodeServerUrl()) { @@ -54354,6 +54395,7 @@ const result_1 = __nccwpck_require__(7305); const issue_repository_1 = __nccwpck_require__(57); const list_utils_1 = __nccwpck_require__(4990); const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); const execute_script_use_case_1 = __nccwpck_require__(155); class NotifyNewCommitOnIssueUseCase { constructor() { @@ -54364,7 +54406,7 @@ class NotifyNewCommitOnIssueUseCase { this.separator = '------------------------------------------------------'; } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const result = []; try { const branchName = param.commit.branch; @@ -54490,13 +54532,14 @@ exports.CheckPermissionsUseCase = void 0; const result_1 = __nccwpck_require__(7305); const project_repository_1 = __nccwpck_require__(7917); const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); class CheckPermissionsUseCase { constructor() { this.taskId = 'CheckPermissionsUseCase'; this.projectRepository = new project_repository_1.ProjectRepository(); } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const result = []; /** * If a release/hotfix issue was opened, check if author is a member of the project. @@ -54578,12 +54621,13 @@ Object.defineProperty(exports, "__esModule", ({ value: true })); exports.CommitPrefixBuilderUseCase = void 0; const result_1 = __nccwpck_require__(7305); const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); class CommitPrefixBuilderUseCase { constructor() { this.taskId = 'CommitPrefixBuilderUseCase'; } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const result = []; try { const branchName = param.commitPrefixBuilderParams.branchName; @@ -54694,13 +54738,14 @@ const result_1 = __nccwpck_require__(7305); const issue_repository_1 = __nccwpck_require__(57); const content_utils_1 = __nccwpck_require__(7873); const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); class GetHotfixVersionUseCase { constructor() { this.taskId = 'GetHotfixVersionUseCase'; this.issueRepository = new issue_repository_1.IssueRepository(); } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const result = []; try { let number = -1; @@ -54791,13 +54836,14 @@ const result_1 = __nccwpck_require__(7305); const issue_repository_1 = __nccwpck_require__(57); const content_utils_1 = __nccwpck_require__(7873); const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); class GetReleaseTypeUseCase { constructor() { this.taskId = 'GetReleaseTypeUseCase'; this.issueRepository = new issue_repository_1.IssueRepository(); } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const result = []; try { let number = -1; @@ -54877,13 +54923,14 @@ const result_1 = __nccwpck_require__(7305); const issue_repository_1 = __nccwpck_require__(57); const content_utils_1 = __nccwpck_require__(7873); const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); class GetReleaseVersionUseCase { constructor() { this.taskId = 'GetReleaseVersionUseCase'; this.issueRepository = new issue_repository_1.IssueRepository(); } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const result = []; try { let number = -1; @@ -55105,13 +55152,14 @@ exports.UpdateTitleUseCase = void 0; const result_1 = __nccwpck_require__(7305); const issue_repository_1 = __nccwpck_require__(57); const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); class UpdateTitleUseCase { constructor() { this.taskId = 'UpdateTitleUseCase'; this.issueRepository = new issue_repository_1.IssueRepository(); } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const result = []; try { if (param.isIssue) { @@ -55223,6 +55271,7 @@ const result_1 = __nccwpck_require__(7305); const issue_repository_1 = __nccwpck_require__(57); const project_repository_1 = __nccwpck_require__(7917); const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); class AssignMemberToIssueUseCase { constructor() { this.taskId = 'AssignMemberToIssueUseCase'; @@ -55230,7 +55279,7 @@ class AssignMemberToIssueUseCase { this.projectRepository = new project_repository_1.ProjectRepository(); } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const desiredAssigneesCount = param.isIssue ? param.issue.desiredAssigneesCount : param.pullRequest.desiredAssigneesCount; const number = param.isIssue ? param.issue.number : param.pullRequest.number; @@ -55344,6 +55393,7 @@ const issue_repository_1 = __nccwpck_require__(57); const project_repository_1 = __nccwpck_require__(7917); const pull_request_repository_1 = __nccwpck_require__(634); const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); class AssignReviewersToIssueUseCase { constructor() { this.taskId = 'AssignReviewersToIssueUseCase'; @@ -55352,7 +55402,7 @@ class AssignReviewersToIssueUseCase { this.projectRepository = new project_repository_1.ProjectRepository(); } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const desiredReviewersCount = param.pullRequest.desiredReviewersCount; const number = param.pullRequest.number; const result = []; @@ -55433,13 +55483,14 @@ exports.CheckPriorityIssueSizeUseCase = void 0; const result_1 = __nccwpck_require__(7305); const project_repository_1 = __nccwpck_require__(7917); const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); class CheckPriorityIssueSizeUseCase { constructor() { this.taskId = 'CheckPriorityIssueSizeUseCase'; this.projectRepository = new project_repository_1.ProjectRepository(); } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const result = []; try { const priority = param.labels.priorityLabelOnIssue; @@ -55517,13 +55568,14 @@ exports.CloseIssueAfterMergingUseCase = void 0; const result_1 = __nccwpck_require__(7305); const issue_repository_1 = __nccwpck_require__(57); const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); class CloseIssueAfterMergingUseCase { constructor() { this.taskId = 'CloseIssueAfterMergingUseCase'; this.issueRepository = new issue_repository_1.IssueRepository(); } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const result = []; try { const closed = await this.issueRepository.closeIssue(param.owner, param.repo, param.issueNumber, param.tokens.token); @@ -55575,13 +55627,14 @@ exports.CloseNotAllowedIssueUseCase = void 0; const result_1 = __nccwpck_require__(7305); const issue_repository_1 = __nccwpck_require__(57); const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); class CloseNotAllowedIssueUseCase { constructor() { this.taskId = 'CloseNotAllowedIssueUseCase'; this.issueRepository = new issue_repository_1.IssueRepository(); } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const result = []; try { const closed = await this.issueRepository.closeIssue(param.owner, param.repo, param.issueNumber, param.tokens.token); @@ -55634,6 +55687,7 @@ const result_1 = __nccwpck_require__(7305); const branch_repository_1 = __nccwpck_require__(7701); const content_utils_1 = __nccwpck_require__(7873); const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); const move_issue_to_in_progress_1 = __nccwpck_require__(8203); class DeployAddedUseCase { constructor() { @@ -55641,7 +55695,7 @@ class DeployAddedUseCase { this.branchRepository = new branch_repository_1.BranchRepository(); } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const result = []; try { if (param.issue.labeled && param.issue.labelAdded === param.labels.deploy) { @@ -55750,12 +55804,13 @@ Object.defineProperty(exports, "__esModule", ({ value: true })); exports.DeployedAddedUseCase = void 0; const result_1 = __nccwpck_require__(7305); const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); class DeployedAddedUseCase { constructor() { this.taskId = 'DeployedAddedUseCase'; } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const result = []; try { if (param.issue.labeled && param.issue.labelAdded === param.labels.deployed) { @@ -55824,6 +55879,7 @@ const result_1 = __nccwpck_require__(7305); const issue_repository_1 = __nccwpck_require__(57); const project_repository_1 = __nccwpck_require__(7917); const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); class LinkIssueProjectUseCase { constructor() { this.taskId = 'LinkIssueProjectUseCase'; @@ -55831,7 +55887,7 @@ class LinkIssueProjectUseCase { this.projectRepository = new project_repository_1.ProjectRepository(); } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const result = []; const columnName = param.project.getProjectColumnIssueCreated(); try { @@ -55896,13 +55952,14 @@ exports.MoveIssueToInProgressUseCase = void 0; const result_1 = __nccwpck_require__(7305); const project_repository_1 = __nccwpck_require__(7917); const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); class MoveIssueToInProgressUseCase { constructor() { this.taskId = 'MoveIssueToInProgressUseCase'; this.projectRepository = new project_repository_1.ProjectRepository(); } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const result = []; const columnName = param.project.getProjectColumnIssueInProgress(); try { @@ -55986,6 +56043,7 @@ const core = __importStar(__nccwpck_require__(2186)); const result_1 = __nccwpck_require__(7305); const branch_repository_1 = __nccwpck_require__(7701); const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); const execute_script_use_case_1 = __nccwpck_require__(155); const move_issue_to_in_progress_1 = __nccwpck_require__(8203); class PrepareBranchesUseCase { @@ -55994,7 +56052,7 @@ class PrepareBranchesUseCase { this.branchRepository = new branch_repository_1.BranchRepository(); } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const result = []; try { const issueTitle = param.issue.title; @@ -56254,6 +56312,7 @@ exports.RemoveIssueBranchesUseCase = void 0; const result_1 = __nccwpck_require__(7305); const branch_repository_1 = __nccwpck_require__(7701); const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); /** * Remove any branch created for this issue */ @@ -56263,7 +56322,7 @@ class RemoveIssueBranchesUseCase { this.branchRepository = new branch_repository_1.BranchRepository(); } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const results = []; try { const branchTypes = [param.branches.featureTree, param.branches.bugfixTree]; @@ -56364,13 +56423,14 @@ const core = __importStar(__nccwpck_require__(2186)); const result_1 = __nccwpck_require__(7305); const branch_repository_1 = __nccwpck_require__(7701); const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); class RemoveNotNeededBranchesUseCase { constructor() { this.taskId = 'RemoveNotNeededBranchesUseCase'; this.branchRepository = new branch_repository_1.BranchRepository(); } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const result = []; try { const issueTitle = param.issue.title; @@ -56481,13 +56541,14 @@ exports.UpdateIssueTypeUseCase = void 0; const result_1 = __nccwpck_require__(7305); const issue_repository_1 = __nccwpck_require__(57); const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); class UpdateIssueTypeUseCase { constructor() { this.taskId = 'UpdateIssueTypeUseCase'; this.issueRepository = new issue_repository_1.IssueRepository(); } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const result = []; try { await this.issueRepository.setIssueType(param.owner, param.repo, param.issueNumber, param.labels, param.issueTypes, param.tokens.token); @@ -56523,6 +56584,7 @@ const result_1 = __nccwpck_require__(7305); const ai_repository_1 = __nccwpck_require__(8307); const issue_repository_1 = __nccwpck_require__(57); const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); class CheckIssueCommentLanguageUseCase { constructor() { this.taskId = 'CheckIssueCommentLanguageUseCase'; @@ -56533,7 +56595,7 @@ If you'd like this comment to be translated again, please delete the entire comm -->`; } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const results = []; const commentBody = param.issue.commentBody; if (commentBody.length === 0 || commentBody.includes(this.translatedKey)) { @@ -56632,13 +56694,14 @@ exports.CheckPriorityPullRequestSizeUseCase = void 0; const result_1 = __nccwpck_require__(7305); const project_repository_1 = __nccwpck_require__(7917); const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); class CheckPriorityPullRequestSizeUseCase { constructor() { this.taskId = 'CheckPriorityPullRequestSizeUseCase'; this.projectRepository = new project_repository_1.ProjectRepository(); } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const result = []; try { const priority = param.labels.priorityLabelOnIssue; @@ -56750,13 +56813,14 @@ const github = __importStar(__nccwpck_require__(5438)); const result_1 = __nccwpck_require__(7305); const pull_request_repository_1 = __nccwpck_require__(634); const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); class LinkPullRequestIssueUseCase { constructor() { this.taskId = 'LinkPullRequestIssueUseCase'; this.pullRequestRepository = new pull_request_repository_1.PullRequestRepository(); } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const result = []; try { const isLinked = await this.pullRequestRepository.isLinked(github.context.payload.pull_request?.html_url ?? ''); @@ -56850,13 +56914,14 @@ exports.LinkPullRequestProjectUseCase = void 0; const result_1 = __nccwpck_require__(7305); const project_repository_1 = __nccwpck_require__(7917); const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); class LinkPullRequestProjectUseCase { constructor() { this.taskId = 'LinkPullRequestProjectUseCase'; this.projectRepository = new project_repository_1.ProjectRepository(); } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const result = []; const columnName = param.project.getProjectColumnPullRequestCreated(); try { @@ -56922,6 +56987,7 @@ exports.SyncSizeAndProgressLabelsFromIssueToPrUseCase = void 0; const result_1 = __nccwpck_require__(7305); const issue_repository_1 = __nccwpck_require__(57); const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); /** * Copies size and progress labels from the linked issue to the PR. * Used when a PR is opened so it gets the same size/progress as the issue (corner case: @@ -56933,7 +56999,7 @@ class SyncSizeAndProgressLabelsFromIssueToPrUseCase { this.issueRepository = new issue_repository_1.IssueRepository(); } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const result = []; try { if (param.issueNumber === -1) { @@ -57007,6 +57073,7 @@ const issue_repository_1 = __nccwpck_require__(57); const project_repository_1 = __nccwpck_require__(7917); const pull_request_repository_1 = __nccwpck_require__(634); const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); class UpdatePullRequestDescriptionUseCase { constructor() { this.taskId = 'UpdatePullRequestDescriptionUseCase'; @@ -57016,7 +57083,7 @@ class UpdatePullRequestDescriptionUseCase { this.projectRepository = new project_repository_1.ProjectRepository(); } async invoke(param) { - (0, logger_1.logDebugInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logDebugInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const result = []; try { const prNumber = param.pullRequest.number; @@ -57143,6 +57210,7 @@ const result_1 = __nccwpck_require__(7305); const ai_repository_1 = __nccwpck_require__(8307); const issue_repository_1 = __nccwpck_require__(57); const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); class CheckPullRequestCommentLanguageUseCase { constructor() { this.taskId = 'CheckPullRequestCommentLanguageUseCase'; @@ -57153,7 +57221,7 @@ If you'd like this comment to be translated again, please delete the entire comm -->`; } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const results = []; const commentBody = param.pullRequest.commentBody; if (commentBody.length === 0 || commentBody.includes(this.translatedKey)) { @@ -57247,10 +57315,9 @@ exports.CheckPullRequestCommentLanguageUseCase = CheckPullRequestCommentLanguage "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.PROMPTS = exports.BUGBOT_MIN_SEVERITY = exports.BUGBOT_MAX_COMMENTS = exports.BUGBOT_MARKER_PREFIX = exports.ACTIONS = exports.ERRORS = exports.INPUT_KEYS = exports.WORKFLOW_ACTIVE_STATUSES = exports.WORKFLOW_STATUS = exports.DEFAULT_IMAGE_CONFIG = exports.OPENCODE_RETRY_DELAY_MS = exports.OPENCODE_MAX_RETRIES = exports.OPENCODE_REQUEST_TIMEOUT_MS = exports.OPENCODE_DEFAULT_MODEL = exports.REPO_URL = exports.TITLE = exports.COMMAND = void 0; -exports.COMMAND = 'giik'; -exports.TITLE = 'Giik'; -exports.REPO_URL = 'https://github.com/landamessenger/git-board-flow'; +exports.PROMPTS = exports.BUGBOT_MIN_SEVERITY = exports.BUGBOT_MAX_COMMENTS = exports.BUGBOT_MARKER_PREFIX = exports.ACTIONS = exports.ERRORS = exports.INPUT_KEYS = exports.WORKFLOW_ACTIVE_STATUSES = exports.WORKFLOW_STATUS = exports.DEFAULT_IMAGE_CONFIG = exports.OPENCODE_RETRY_DELAY_MS = exports.OPENCODE_MAX_RETRIES = exports.OPENCODE_REQUEST_TIMEOUT_MS = exports.OPENCODE_DEFAULT_MODEL = exports.REPO_URL = exports.TITLE = void 0; +exports.TITLE = 'Copilot'; +exports.REPO_URL = 'https://github.com/vypdev/copilot'; /** Default OpenCode model: provider/modelID (e.g. opencode/kimi-k2.5-free). Reuse for CLI, action and Ai fallbacks. */ exports.OPENCODE_DEFAULT_MODEL = 'opencode/kimi-k2.5-free'; /** Timeout in ms for OpenCode HTTP requests (session create, message, diff). Agent calls can be slow (e.g. plan analyzing repo). */ @@ -57614,8 +57681,8 @@ exports.ACTIONS = { DETECT_POTENTIAL_PROBLEMS: 'detect_potential_problems_action', RECOMMEND_STEPS: 'recommend_steps_action', }; -/** Hidden HTML comment prefix for bugbot findings (issue/PR comments). Format: */ -exports.BUGBOT_MARKER_PREFIX = 'gbf-bugbot'; +/** Hidden HTML comment prefix for bugbot findings (issue/PR comments). Format: */ +exports.BUGBOT_MARKER_PREFIX = 'copilot-bugbot'; /** Max number of individual bugbot comments to create per issue/PR. Excess findings get one summary comment suggesting to review locally. */ exports.BUGBOT_MAX_COMMENTS = 20; /** Minimum severity to publish (findings below this are dropped). Order: high > medium > low > info. */ @@ -57892,6 +57959,226 @@ const waitForPreviousRuns = async (params) => { exports.waitForPreviousRuns = waitForPreviousRuns; +/***/ }), + +/***/ 1666: +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { + +"use strict"; + +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || (function () { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function (o) { + var ar = []; + for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + __setModuleDefault(result, mod); + return result; + }; +})(); +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.ensureGitHubDirs = ensureGitHubDirs; +exports.copySetupFiles = copySetupFiles; +const fs = __importStar(__nccwpck_require__(7147)); +const path = __importStar(__nccwpck_require__(1017)); +const logger_1 = __nccwpck_require__(8836); +/** + * Ensure .github, .github/workflows and .github/ISSUE_TEMPLATE exist; create them if missing. + * @param cwd - Directory (repo root) + */ +function ensureGitHubDirs(cwd) { + const githubDir = path.join(cwd, '.github'); + const workflowsDir = path.join(cwd, '.github', 'workflows'); + const issueTemplateDir = path.join(cwd, '.github', 'ISSUE_TEMPLATE'); + if (!fs.existsSync(githubDir)) { + (0, logger_1.logInfo)('📁 Creating .github/...'); + fs.mkdirSync(githubDir, { recursive: true }); + } + if (!fs.existsSync(workflowsDir)) { + (0, logger_1.logInfo)('📁 Creating .github/workflows/...'); + fs.mkdirSync(workflowsDir, { recursive: true }); + } + if (!fs.existsSync(issueTemplateDir)) { + (0, logger_1.logInfo)('📁 Creating .github/ISSUE_TEMPLATE/...'); + fs.mkdirSync(issueTemplateDir, { recursive: true }); + } +} +/** + * Copy setup files from setup/ to repo (.github/ workflows, ISSUE_TEMPLATE, pull_request_template.md, .env at root). + * Skips files that already exist at destination (no overwrite). + * Logs each file copied or skipped. No-op if setup/ does not exist. + * @param cwd - Repo root + * @returns { copied, skipped } + */ +function copySetupFiles(cwd) { + const setupDir = path.join(cwd, 'setup'); + if (!fs.existsSync(setupDir)) + return { copied: 0, skipped: 0 }; + let copied = 0; + let skipped = 0; + const workflowsSrc = path.join(setupDir, 'workflows'); + const workflowsDst = path.join(cwd, '.github', 'workflows'); + if (fs.existsSync(workflowsSrc)) { + const files = fs.readdirSync(workflowsSrc).filter((f) => f.endsWith('.yml') || f.endsWith('.yaml')); + for (const f of files) { + const src = path.join(workflowsSrc, f); + const dst = path.join(workflowsDst, f); + if (fs.statSync(src).isFile()) { + if (fs.existsSync(dst)) { + (0, logger_1.logInfo)(` ⏭️ .github/workflows/${f} already exists; skipping.`); + skipped += 1; + } + else { + fs.copyFileSync(src, dst); + (0, logger_1.logInfo)(` ✅ Copied setup/workflows/${f} → .github/workflows/${f}`); + copied += 1; + } + } + } + } + const issueTemplateSrc = path.join(setupDir, 'ISSUE_TEMPLATE'); + const issueTemplateDst = path.join(cwd, '.github', 'ISSUE_TEMPLATE'); + if (fs.existsSync(issueTemplateSrc)) { + const files = fs.readdirSync(issueTemplateSrc).filter((f) => fs.statSync(path.join(issueTemplateSrc, f)).isFile()); + for (const f of files) { + const src = path.join(issueTemplateSrc, f); + const dst = path.join(issueTemplateDst, f); + if (fs.existsSync(dst)) { + (0, logger_1.logInfo)(` ⏭️ .github/ISSUE_TEMPLATE/${f} already exists; skipping.`); + skipped += 1; + } + else { + fs.copyFileSync(src, dst); + (0, logger_1.logInfo)(` ✅ Copied setup/ISSUE_TEMPLATE/${f} → .github/ISSUE_TEMPLATE/${f}`); + copied += 1; + } + } + } + const prTemplateSrc = path.join(setupDir, 'pull_request_template.md'); + const prTemplateDst = path.join(cwd, '.github', 'pull_request_template.md'); + if (fs.existsSync(prTemplateSrc)) { + if (fs.existsSync(prTemplateDst)) { + (0, logger_1.logInfo)(' ⏭️ .github/pull_request_template.md already exists; skipping.'); + skipped += 1; + } + else { + fs.copyFileSync(prTemplateSrc, prTemplateDst); + (0, logger_1.logInfo)(' ✅ Copied setup/pull_request_template.md → .github/pull_request_template.md'); + copied += 1; + } + } + const envSrc = path.join(setupDir, '.env'); + const envDst = path.join(cwd, '.env'); + if (fs.existsSync(envSrc) && fs.statSync(envSrc).isFile()) { + if (fs.existsSync(envDst)) { + (0, logger_1.logInfo)(' ⏭️ .env already exists; skipping.'); + skipped += 1; + } + else { + fs.copyFileSync(envSrc, envDst); + (0, logger_1.logInfo)(' ✅ Copied setup/.env → .env'); + copied += 1; + } + } + return { copied, skipped }; +} + + +/***/ }), + +/***/ 9785: +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.getTaskEmoji = getTaskEmoji; +/** + * Representative emoji per task for "Executing {taskId}" logs. + * Makes it easier to visually identify the step type in the action output. + */ +const TASK_EMOJI = { + // Main use cases + CommitUseCase: '📤', + IssueUseCase: '📋', + PullRequestUseCase: '🔀', + IssueCommentUseCase: '💬', + PullRequestReviewCommentUseCase: '💬', + SingleActionUseCase: '⚡', + // Issue steps + PrepareBranchesUseCase: '🌿', + CheckPermissionsUseCase: '🔐', + UpdateTitleUseCase: '✏️', + AssignMemberToIssueUseCase: '👤', + AssignReviewersToIssueUseCase: '👀', + LinkIssueProjectUseCase: '🔗', + LinkPullRequestProjectUseCase: '🔗', + LinkPullRequestIssueUseCase: '🔗', + CheckPriorityIssueSizeUseCase: '📏', + CheckPriorityPullRequestSizeUseCase: '📏', + CloseNotAllowedIssueUseCase: '🚫', + CloseIssueAfterMergingUseCase: '✅', + RemoveIssueBranchesUseCase: '🧹', + RemoveNotNeededBranchesUseCase: '🧹', + DeployAddedUseCase: '🏷️', + DeployedAddedUseCase: '🏷️', + MoveIssueToInProgressUseCase: '📥', + UpdateIssueTypeUseCase: '🏷️', + // Commit steps + NotifyNewCommitOnIssueUseCase: '📢', + CheckChangesIssueSizeUseCase: '📐', + DetectPotentialProblemsUseCase: '🔍', + // PR steps + SyncSizeAndProgressLabelsFromIssueToPrUseCase: '🔄', + UpdatePullRequestDescriptionUseCase: '✏️', + CheckIssueCommentLanguageUseCase: '🌐', + CheckPullRequestCommentLanguageUseCase: '🌐', + // Common steps + PublishResultUseCase: '📄', + StoreConfigurationUseCase: '⚙️', + GetReleaseVersionUseCase: '🏷️', + GetReleaseTypeUseCase: '🏷️', + GetHotfixVersionUseCase: '🏷️', + CommitPrefixBuilderUseCase: '📜', + ThinkUseCase: '💭', + // Actions + CheckProgressUseCase: '📊', + RecommendStepsUseCase: '💡', + CreateReleaseUseCase: '🎉', + CreateTagUseCase: '🏷️', + PublishGithubActionUseCase: '📦', + DeployedActionUseCase: '🚀', + InitialSetupUseCase: '🛠️', +}; +const DEFAULT_EMOJI = '▶️'; +function getTaskEmoji(taskId) { + return TASK_EMOJI[taskId] ?? DEFAULT_EMOJI; +} + + /***/ }), /***/ 6676: diff --git a/build/cli/src/agent/__tests__/base_tool.test.d.ts b/build/cli/src/agent/__tests__/base_tool.test.d.ts deleted file mode 100644 index 97f7a014..00000000 --- a/build/cli/src/agent/__tests__/base_tool.test.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Tests for BaseTool - */ -export {}; diff --git a/build/cli/src/agent/__tests__/budget_manager.test.d.ts b/build/cli/src/agent/__tests__/budget_manager.test.d.ts deleted file mode 100644 index 603d68c8..00000000 --- a/build/cli/src/agent/__tests__/budget_manager.test.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Tests for BudgetManager - */ -export {}; diff --git a/build/cli/src/agent/__tests__/context_manager.test.d.ts b/build/cli/src/agent/__tests__/context_manager.test.d.ts deleted file mode 100644 index 2b59f0eb..00000000 --- a/build/cli/src/agent/__tests__/context_manager.test.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Tests for ContextManager - */ -export {}; diff --git a/build/cli/src/agent/__tests__/context_sharing.test.d.ts b/build/cli/src/agent/__tests__/context_sharing.test.d.ts deleted file mode 100644 index 698ebf25..00000000 --- a/build/cli/src/agent/__tests__/context_sharing.test.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Tests for Context Sharing - */ -export {}; diff --git a/build/cli/src/agent/__tests__/mcp_client.test.d.ts b/build/cli/src/agent/__tests__/mcp_client.test.d.ts deleted file mode 100644 index f911b74e..00000000 --- a/build/cli/src/agent/__tests__/mcp_client.test.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Tests for MCP Client - */ -export {}; diff --git a/build/cli/src/agent/__tests__/mcp_manager.test.d.ts b/build/cli/src/agent/__tests__/mcp_manager.test.d.ts deleted file mode 100644 index 2f119963..00000000 --- a/build/cli/src/agent/__tests__/mcp_manager.test.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Tests for MCP Manager - */ -export {}; diff --git a/build/cli/src/agent/__tests__/message_manager.test.d.ts b/build/cli/src/agent/__tests__/message_manager.test.d.ts deleted file mode 100644 index b2cd7b25..00000000 --- a/build/cli/src/agent/__tests__/message_manager.test.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Tests for MessageManager - */ -export {}; diff --git a/build/cli/src/agent/__tests__/metrics_tracker.test.d.ts b/build/cli/src/agent/__tests__/metrics_tracker.test.d.ts deleted file mode 100644 index 713b266a..00000000 --- a/build/cli/src/agent/__tests__/metrics_tracker.test.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Tests for MetricsTracker - */ -export {}; diff --git a/build/cli/src/agent/__tests__/response_parser.test.d.ts b/build/cli/src/agent/__tests__/response_parser.test.d.ts deleted file mode 100644 index e23f57ba..00000000 --- a/build/cli/src/agent/__tests__/response_parser.test.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Tests for ResponseParser - */ -export {}; diff --git a/build/cli/src/agent/__tests__/retry_manager.test.d.ts b/build/cli/src/agent/__tests__/retry_manager.test.d.ts deleted file mode 100644 index 06395513..00000000 --- a/build/cli/src/agent/__tests__/retry_manager.test.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Tests for RetryManager - */ -export {}; diff --git a/build/cli/src/agent/__tests__/session_manager.test.d.ts b/build/cli/src/agent/__tests__/session_manager.test.d.ts deleted file mode 100644 index bc6b4113..00000000 --- a/build/cli/src/agent/__tests__/session_manager.test.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Tests for SessionManager - */ -export {}; diff --git a/build/cli/src/agent/__tests__/subagent_manager.test.d.ts b/build/cli/src/agent/__tests__/subagent_manager.test.d.ts deleted file mode 100644 index 519f7016..00000000 --- a/build/cli/src/agent/__tests__/subagent_manager.test.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Tests for SubAgent Manager - */ -export {}; diff --git a/build/cli/src/agent/__tests__/tool_executor.test.d.ts b/build/cli/src/agent/__tests__/tool_executor.test.d.ts deleted file mode 100644 index a8da0023..00000000 --- a/build/cli/src/agent/__tests__/tool_executor.test.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Tests for ToolExecutor - */ -export {}; diff --git a/build/cli/src/agent/__tests__/tool_permissions.test.d.ts b/build/cli/src/agent/__tests__/tool_permissions.test.d.ts deleted file mode 100644 index a447c3e5..00000000 --- a/build/cli/src/agent/__tests__/tool_permissions.test.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Tests for ToolPermissionsManager - */ -export {}; diff --git a/build/cli/src/agent/__tests__/tool_registry.test.d.ts b/build/cli/src/agent/__tests__/tool_registry.test.d.ts deleted file mode 100644 index 75f92c3e..00000000 --- a/build/cli/src/agent/__tests__/tool_registry.test.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Tests for ToolRegistry - */ -export {}; diff --git a/build/cli/src/agent/core/agent.d.ts b/build/cli/src/agent/core/agent.d.ts deleted file mode 100644 index 05f5f731..00000000 --- a/build/cli/src/agent/core/agent.d.ts +++ /dev/null @@ -1,112 +0,0 @@ -/** - * Agent - Main class for Agent SDK - * Similar to Anthropic's Agent SDK - * Integrated with all advanced features - */ -import { BaseTool } from '../tools/base_tool'; -import { AgentOptions, AgentResult, Message } from '../types'; -import { SubAgentManager, SubAgentOptions, Task } from './subagent_manager'; -export declare class Agent { - private options; - private messageManager; - private toolRegistry; - private toolExecutor; - private reasoningLoop; - private sessionManager; - private subAgentManager?; - private sessionId; - constructor(options: AgentOptions); - /** - * Execute query - main entry point - * Similar to Agent SDK's query() method - */ - query(prompt: string): Promise; - /** - * Continue conversation with additional prompt - */ - continue(prompt: string): Promise; - /** - * Load session - */ - loadSession(sessionId?: string): Promise; - /** - * Save session - */ - private saveSession; - /** - * Get session ID - */ - getSessionId(): string; - /** - * List all sessions - */ - listSessions(): Promise; - /** - * Delete session - */ - deleteSession(sessionId?: string): Promise; - /** - * Get message history - */ - getMessages(): Message[]; - /** - * Get message count - */ - getMessageCount(): number; - /** - * Reset agent (clear history) - */ - reset(): void; - /** - * Register a tool - */ - registerTool(tool: BaseTool): void; - /** - * Register multiple tools - */ - registerTools(tools: BaseTool[]): void; - /** - * Get available tools - */ - getAvailableTools(): string[]; - /** - * Get system prompt - */ - getSystemPrompt(): string | undefined; - /** - * Update system prompt - */ - setSystemPrompt(prompt: string): void; - /** - * Create a subagent - */ - createSubAgent(options: SubAgentOptions): Agent; - /** - * Execute multiple tasks in parallel using subagents - */ - executeParallel(tasks: Task[]): Promise>; - /** - * Coordinate agents with dependencies - */ - coordinateAgents(tasks: Array): Promise>; - /** - * Get subagent manager - */ - getSubAgentManager(): SubAgentManager | undefined; - /** - * Get subagent by name - */ - getSubAgent(name: string): Agent | undefined; - /** - * Get all subagents - */ - getAllSubAgents(): Agent[]; -} diff --git a/build/cli/src/agent/core/budget_manager.d.ts b/build/cli/src/agent/core/budget_manager.d.ts deleted file mode 100644 index e9b8d747..00000000 --- a/build/cli/src/agent/core/budget_manager.d.ts +++ /dev/null @@ -1,45 +0,0 @@ -/** - * Budget Manager - * Tracks and enforces budget limits - */ -import { BudgetConfig } from '../types/agent_types'; -import { Metrics } from '../types/agent_types'; -export declare class BudgetManager { - private config; - private currentCost; - private currentTokens; - constructor(config?: BudgetConfig); - /** - * Check if budget is exceeded - */ - isExceeded(metrics: Metrics): boolean; - /** - * Check if budget warning should be shown - */ - shouldWarn(metrics: Metrics): boolean; - /** - * Get budget status - */ - getStatus(metrics: Metrics): { - exceeded: boolean; - warning: boolean; - tokenUsage?: { - used: number; - limit: number; - percent: number; - }; - costUsage?: { - used: number; - limit: number; - percent: number; - }; - }; - /** - * Log budget status - */ - logStatus(metrics: Metrics): void; - /** - * Update budget config - */ - updateConfig(config: BudgetConfig): void; -} diff --git a/build/cli/src/agent/core/context_manager.d.ts b/build/cli/src/agent/core/context_manager.d.ts deleted file mode 100644 index 918c6277..00000000 --- a/build/cli/src/agent/core/context_manager.d.ts +++ /dev/null @@ -1,39 +0,0 @@ -/** - * Context Manager - * Manages conversation context and compression for long conversations - */ -import { Message } from '../types/message_types'; -export interface ContextStats { - messageCount: number; - estimatedTokens: number; - compressed: boolean; -} -export declare class ContextManager { - private maxContextLength; - private compressionEnabled; - constructor(maxContextLength?: number, compressionEnabled?: boolean); - /** - * Estimate tokens in messages (rough approximation: 1 token ≈ 4 characters) - */ - estimateTokens(messages: Message[]): number; - /** - * Check if context needs compression - */ - needsCompression(messages: Message[]): boolean; - /** - * Compress context by summarizing old messages - */ - compressContext(messages: Message[]): Message[]; - /** - * Get context statistics - */ - getStats(messages: Message[]): ContextStats; - /** - * Update max context length - */ - setMaxContextLength(length: number): void; - /** - * Enable/disable compression - */ - setCompressionEnabled(enabled: boolean): void; -} diff --git a/build/cli/src/agent/core/context_sharing.d.ts b/build/cli/src/agent/core/context_sharing.d.ts deleted file mode 100644 index 2651ae81..00000000 --- a/build/cli/src/agent/core/context_sharing.d.ts +++ /dev/null @@ -1,35 +0,0 @@ -/** - * Context Sharing - * Manages sharing context between agents - */ -import { Message } from '../types'; -import { MessageManager } from './message_manager'; -export interface SharedContext { - messages: Message[]; - metadata?: Record; -} -export declare class ContextSharing { - /** - * Extract relevant messages from an agent - */ - static extractRelevantMessages(messages: Message[], maxMessages?: number): Message[]; - /** - * Share context between agents - */ - static shareContext(fromMessages: Message[], toMessageManager: MessageManager, options?: { - includeSystem?: boolean; - maxMessages?: number; - filterByRole?: ('user' | 'assistant' | 'system')[]; - }): void; - /** - * Merge contexts from multiple agents - */ - static mergeContexts(contexts: Message[][], options?: { - deduplicate?: boolean; - maxMessages?: number; - }): Message[]; - /** - * Create a summary of context for sharing - */ - static createContextSummary(messages: Message[]): string; -} diff --git a/build/cli/src/agent/core/index.d.ts b/build/cli/src/agent/core/index.d.ts deleted file mode 100644 index 80777f02..00000000 --- a/build/cli/src/agent/core/index.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -/** - * Export core components - */ -export * from './message_manager'; -export * from './reasoning_loop'; -export * from './agent'; diff --git a/build/cli/src/agent/core/message_manager.d.ts b/build/cli/src/agent/core/message_manager.d.ts deleted file mode 100644 index 1cd6f7ae..00000000 --- a/build/cli/src/agent/core/message_manager.d.ts +++ /dev/null @@ -1,49 +0,0 @@ -/** - * Message Manager for Agent SDK - * Manages conversation history in Anthropic Messages API format - */ -import { Message, ContentBlock } from '../types'; -import { ToolResult } from '../types'; -export declare class MessageManager { - private messages; - /** - * Add system message (only one allowed, at the beginning) - */ - addSystemMessage(content: string): void; - /** - * Add user message - */ - addUserMessage(content: string | ContentBlock[]): void; - /** - * Add assistant message - */ - addAssistantMessage(content: string | ContentBlock[]): void; - /** - * Add tool results as user message - */ - addToolResults(results: ToolResult[]): void; - /** - * Get all messages - */ - getMessages(): Message[]; - /** - * Get messages count - */ - getMessageCount(): number; - /** - * Get last message - */ - getLastMessage(): Message | undefined; - /** - * Reset message history - */ - reset(): void; - /** - * Check if has system message - */ - hasSystemMessage(): boolean; - /** - * Get system message if exists - */ - getSystemMessage(): string | undefined; -} diff --git a/build/cli/src/agent/core/metrics_tracker.d.ts b/build/cli/src/agent/core/metrics_tracker.d.ts deleted file mode 100644 index a3188919..00000000 --- a/build/cli/src/agent/core/metrics_tracker.d.ts +++ /dev/null @@ -1,40 +0,0 @@ -/** - * Metrics Tracker - * Tracks tokens, costs, latency, and other metrics - */ -import { Metrics } from '../types/agent_types'; -export interface CostConfig { - inputCostPer1kTokens: number; - outputCostPer1kTokens: number; -} -export declare class MetricsTracker { - private metrics; - private startTime; - private apiCallTimes; - private costConfig?; - constructor(costConfig?: CostConfig); - /** - * Record API call with tokens and latency - */ - recordAPICall(inputTokens: number, outputTokens: number, latency: number): void; - /** - * Record tool call - */ - recordToolCall(): void; - /** - * Record error - */ - recordError(): void; - /** - * Get current metrics - */ - getMetrics(): Metrics; - /** - * Reset metrics - */ - reset(): void; - /** - * Set cost configuration - */ - setCostConfig(config: CostConfig): void; -} diff --git a/build/cli/src/agent/core/reasoning_loop.d.ts b/build/cli/src/agent/core/reasoning_loop.d.ts deleted file mode 100644 index a21f9e57..00000000 --- a/build/cli/src/agent/core/reasoning_loop.d.ts +++ /dev/null @@ -1,55 +0,0 @@ -/** - * Reasoning Loop for Agent SDK - * Manages the conversation loop with tool calling - * Integrated with all advanced features: streaming, permissions, context, metrics, budget, timeouts, retry - */ -import { MessageManager } from './message_manager'; -import { ToolExecutor } from '../tools/tool_executor'; -import { AgentOptions, AgentResult } from '../types'; -export declare class ReasoningLoop { - private messageManager; - private toolExecutor; - private options; - private aiRepository; - private ai; - private permissionsManager; - private contextManager; - private metricsTracker; - private budgetManager; - private retryManager; - private sessionStartTime; - private timeoutId?; - constructor(messageManager: MessageManager, toolExecutor: ToolExecutor, options: AgentOptions); - /** - * Execute the reasoning loop - */ - execute(): Promise; - /** - * Call API with retry logic - */ - private callAPIWithRetry; - /** - * Call OpenCode API via AiRepository - */ - private callAPI; - /** - * Execute tools with timeout - */ - private executeToolsWithTimeout; - /** - * Create timeout promise - */ - private createTimeoutPromise; - /** - * Estimate input tokens (rough approximation) - */ - private estimateInputTokens; - /** - * Parse API response - */ - private parseResponse; - /** - * Create result object - */ - private createResult; -} diff --git a/build/cli/src/agent/core/retry_manager.d.ts b/build/cli/src/agent/core/retry_manager.d.ts deleted file mode 100644 index f12e42d4..00000000 --- a/build/cli/src/agent/core/retry_manager.d.ts +++ /dev/null @@ -1,30 +0,0 @@ -/** - * Retry Manager - * Handles retries with exponential backoff and circuit breaker - */ -import { RetryConfig } from '../types/agent_types'; -export declare class RetryManager { - private config; - private circuitBreakerState; - private circuitBreakerFailures; - private circuitBreakerLastFailure; - private readonly circuitBreakerThreshold; - private readonly circuitBreakerTimeout; - constructor(config?: RetryConfig); - /** - * Execute function with retry logic - */ - execute(fn: () => Promise, errorHandler?: (error: any, attempt: number) => boolean): Promise; - /** - * Check if error is retryable - */ - private isRetryableError; - /** - * Sleep utility - */ - private sleep; - /** - * Reset circuit breaker - */ - resetCircuitBreaker(): void; -} diff --git a/build/cli/src/agent/core/session_manager.d.ts b/build/cli/src/agent/core/session_manager.d.ts deleted file mode 100644 index 9dd91646..00000000 --- a/build/cli/src/agent/core/session_manager.d.ts +++ /dev/null @@ -1,55 +0,0 @@ -/** - * Session Manager - * Manages agent sessions with persistence - */ -import { Message } from '../types/message_types'; -import { AgentResult, Metrics } from '../types/agent_types'; -export interface SessionMetadata { - sessionId: string; - createdAt: number; - lastUpdated: number; - messageCount: number; - turnCount: number; - toolCallCount: number; - metrics?: Metrics; -} -export interface SessionData { - metadata: SessionMetadata; - messages: Message[]; -} -export declare class SessionManager { - private sessionsDir; - constructor(sessionsDir?: string); - /** - * Ensure sessions directory exists - */ - private ensureSessionsDir; - /** - * Get session file path - */ - private getSessionPath; - /** - * Save session - */ - saveSession(sessionId: string, messages: Message[], result?: AgentResult): Promise; - /** - * Load session - */ - loadSession(sessionId: string): Promise; - /** - * Delete session - */ - deleteSession(sessionId: string): Promise; - /** - * List all sessions - */ - listSessions(): Promise; - /** - * Get session creation time - */ - private getSessionCreatedAt; - /** - * Generate new session ID - */ - generateSessionId(): string; -} diff --git a/build/cli/src/agent/core/subagent_manager.d.ts b/build/cli/src/agent/core/subagent_manager.d.ts deleted file mode 100644 index 83f15559..00000000 --- a/build/cli/src/agent/core/subagent_manager.d.ts +++ /dev/null @@ -1,77 +0,0 @@ -/** - * SubAgent Manager - * Manages subagents and their coordination - */ -import { Agent } from './agent'; -import { AgentOptions, AgentResult } from '../types'; -export interface SubAgentOptions { - name: string; - systemPrompt?: string; - tools?: any[]; - inheritTools?: boolean; - inheritContext?: boolean; - maxTurns?: number; - maxTokens?: number; - temperature?: number; -} -export interface Task { - name: string; - prompt: string; - systemPrompt?: string; - tools?: any[]; - options?: Partial; -} -export declare class SubAgentManager { - private subAgents; - private parentAgent; - private sharedContext; - constructor(parentAgent: Agent); - /** - * Create a subagent - */ - createSubAgent(options: SubAgentOptions): Agent; - /** - * Internal method to create subagent with options - */ - private createSubAgentWithOptions; - /** - * Execute multiple agents in parallel - */ - executeParallel(tasks: Task[]): Promise>; - /** - * Coordinate agents - execute with dependency management - */ - coordinateAgents(tasks: Array): Promise>; - /** - * Share context between subagents - */ - shareContext(fromAgentName: string, toAgentName: string): void; - /** - * Get subagent by name - */ - getSubAgent(name: string): Agent | undefined; - /** - * Get all subagents - */ - getAllSubAgents(): Agent[]; - /** - * Get subagent names - */ - getSubAgentNames(): string[]; - /** - * Remove subagent - */ - removeSubAgent(name: string): void; - /** - * Clear all subagents - */ - clear(): void; -} diff --git a/build/cli/src/agent/core/tool_permissions.d.ts b/build/cli/src/agent/core/tool_permissions.d.ts deleted file mode 100644 index f4d93f62..00000000 --- a/build/cli/src/agent/core/tool_permissions.d.ts +++ /dev/null @@ -1,25 +0,0 @@ -/** - * Tool Permissions Manager - * Controls which tools the agent can use - */ -import { ToolPermissions } from '../types/agent_types'; -export declare class ToolPermissionsManager { - private permissions; - constructor(permissions?: ToolPermissions); - /** - * Check if a tool is allowed - */ - isAllowed(toolName: string): boolean; - /** - * Get all allowed tool names from a list - */ - filterAllowed(toolNames: string[]): string[]; - /** - * Update permissions - */ - updatePermissions(permissions: ToolPermissions): void; - /** - * Get current permissions - */ - getPermissions(): ToolPermissions; -} diff --git a/build/cli/src/agent/index.d.ts b/build/cli/src/agent/index.d.ts deleted file mode 100644 index d70c45a1..00000000 --- a/build/cli/src/agent/index.d.ts +++ /dev/null @@ -1,20 +0,0 @@ -/** - * Agent SDK - Main exports - * Compatible with Anthropic Agent SDK interface - */ -export { Agent } from './core/agent'; -export { MessageManager } from './core/message_manager'; -export { ReasoningLoop } from './core/reasoning_loop'; -export { ToolPermissionsManager } from './core/tool_permissions'; -export { ContextManager } from './core/context_manager'; -export { SessionManager } from './core/session_manager'; -export { MetricsTracker } from './core/metrics_tracker'; -export { BudgetManager } from './core/budget_manager'; -export { RetryManager } from './core/retry_manager'; -export { BaseTool } from './tools/base_tool'; -export { ToolRegistry } from './tools/tool_registry'; -export { ToolExecutor } from './tools/tool_executor'; -export * from './types'; -export * from './utils'; -export { SubAgentManager } from './core/subagent_manager'; -export { ContextSharing } from './core/context_sharing'; diff --git a/build/cli/src/agent/mcp/index.d.ts b/build/cli/src/agent/mcp/index.d.ts deleted file mode 100644 index 4c7dce18..00000000 --- a/build/cli/src/agent/mcp/index.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -/** - * MCP Module Exports - */ -export { MCPClient } from './mcp_client'; -export { MCPManager } from './mcp_manager'; -export { MCPToolWrapper } from './mcp_tool'; -export { StdioTransport, HTTPTransport, SSETransport, MCPTransport } from './mcp_transport'; -export * from './types'; diff --git a/build/cli/src/agent/mcp/mcp_client.d.ts b/build/cli/src/agent/mcp/mcp_client.d.ts deleted file mode 100644 index 033f96ce..00000000 --- a/build/cli/src/agent/mcp/mcp_client.d.ts +++ /dev/null @@ -1,67 +0,0 @@ -/** - * MCP Client - * Client for Model Context Protocol - */ -import { MCPServerConfig, MCPMessage, MCPTool, MCPResource, MCPPrompt } from './types'; -export declare class MCPClient { - private transports; - private tools; - private resources; - private prompts; - /** - * Connect to an MCP server - */ - connect(config: MCPServerConfig): Promise; - /** - * Initialize MCP connection - */ - private initialize; - /** - * Load tools from MCP server - */ - private loadTools; - /** - * Load resources from MCP server - */ - private loadResources; - /** - * Load prompts from MCP server - */ - private loadPrompts; - /** - * Send request to MCP server - */ - sendRequest(serverName: string, method: string, params?: any): Promise; - /** - * Call an MCP tool - */ - callTool(serverName: string, toolName: string, input: Record): Promise; - /** - * Get all available tools - */ - getTools(): MCPTool[]; - /** - * Get tool by name - */ - getTool(serverName: string, toolName: string): MCPTool | undefined; - /** - * Get all available resources - */ - getResources(): MCPResource[]; - /** - * Get all available prompts - */ - getPrompts(): MCPPrompt[]; - /** - * Check if server is connected - */ - isConnected(serverName: string): boolean; - /** - * Disconnect from MCP server - */ - disconnect(serverName: string): Promise; - /** - * Disconnect from all servers - */ - disconnectAll(): Promise; -} diff --git a/build/cli/src/agent/mcp/mcp_manager.d.ts b/build/cli/src/agent/mcp/mcp_manager.d.ts deleted file mode 100644 index ba3e64b9..00000000 --- a/build/cli/src/agent/mcp/mcp_manager.d.ts +++ /dev/null @@ -1,48 +0,0 @@ -/** - * MCP Manager - * Manages MCP connections and tool registration - */ -import { MCPClient } from './mcp_client'; -import { MCPServerConfig } from './types'; -import { ToolRegistry } from '../tools/tool_registry'; -export interface MCPConfig { - mcpServers: Record; -} -export declare class MCPManager { - private client; - private toolRegistry; - private connectedServers; - constructor(toolRegistry: ToolRegistry); - /** - * Load MCP configuration from file - */ - loadConfig(configPath?: string): Promise; - /** - * Initialize MCP connections from config - */ - initialize(configPath?: string): Promise; - /** - * Connect to an MCP server - */ - connectServer(config: MCPServerConfig): Promise; - /** - * Disconnect from an MCP server - */ - disconnectServer(serverName: string): Promise; - /** - * Get MCP client - */ - getClient(): MCPClient; - /** - * Check if server is connected - */ - isConnected(serverName: string): boolean; - /** - * Get connected servers - */ - getConnectedServers(): string[]; - /** - * Disconnect from all servers - */ - disconnectAll(): Promise; -} diff --git a/build/cli/src/agent/mcp/mcp_tool.d.ts b/build/cli/src/agent/mcp/mcp_tool.d.ts deleted file mode 100644 index 25cb8a0b..00000000 --- a/build/cli/src/agent/mcp/mcp_tool.d.ts +++ /dev/null @@ -1,22 +0,0 @@ -/** - * MCP Tool - * Wrapper for MCP tools to integrate with BaseTool interface - */ -import { BaseTool } from '../tools/base_tool'; -import { MCPClient } from './mcp_client'; -import { MCPTool } from './types'; -export declare class MCPToolWrapper extends BaseTool { - private mcpClient; - private serverName; - private mcpTool; - constructor(mcpClient: MCPClient, serverName: string, mcpTool: MCPTool); - getName(): string; - getDescription(): string; - getInputSchema(): { - type: 'object'; - properties: Record; - required: string[]; - additionalProperties?: boolean; - }; - execute(input: Record): Promise; -} diff --git a/build/cli/src/agent/mcp/mcp_transport.d.ts b/build/cli/src/agent/mcp/mcp_transport.d.ts deleted file mode 100644 index ac854b8e..00000000 --- a/build/cli/src/agent/mcp/mcp_transport.d.ts +++ /dev/null @@ -1,62 +0,0 @@ -/** - * MCP Transport - * Handles communication with MCP servers via different transports - */ -import { MCPMessage } from './types'; -export interface MCPTransport { - send(message: MCPMessage): Promise; - receive(): Promise; - close(): Promise; - isConnected(): boolean; -} -/** - * STDIO Transport - for local processes - */ -export declare class StdioTransport implements MCPTransport { - private command; - private args; - private env; - private process?; - private messageQueue; - private messageHandlers; - private connected; - constructor(command: string, args?: string[], env?: Record); - connect(): Promise; - send(message: MCPMessage): Promise; - receive(): Promise; - private handleMessage; - sendRequest(method: string, params?: any): Promise; - close(): Promise; - isConnected(): boolean; -} -/** - * HTTP Transport - for remote MCP servers - */ -export declare class HTTPTransport implements MCPTransport { - private url; - private headers; - private connected; - constructor(url: string, headers?: Record); - connect(): Promise; - send(message: MCPMessage): Promise; - receive(): Promise; - sendRequest(method: string, params?: any): Promise; - close(): Promise; - isConnected(): boolean; -} -/** - * SSE Transport - for Server-Sent Events - */ -export declare class SSETransport implements MCPTransport { - private url; - private headers; - private eventSource?; - private messageHandlers; - private connected; - constructor(url: string, headers?: Record); - connect(): Promise; - send(message: MCPMessage): Promise; - receive(): Promise; - close(): Promise; - isConnected(): boolean; -} diff --git a/build/cli/src/agent/mcp/types.d.ts b/build/cli/src/agent/mcp/types.d.ts deleted file mode 100644 index 42a702b9..00000000 --- a/build/cli/src/agent/mcp/types.d.ts +++ /dev/null @@ -1,63 +0,0 @@ -/** - * MCP Types - * Types for Model Context Protocol - */ -export interface MCPServerConfig { - name: string; - command?: string; - args?: string[]; - env?: Record; - url?: string; - headers?: Record; - transport?: 'stdio' | 'http' | 'sse'; -} -export interface MCPMessage { - jsonrpc: '2.0'; - id?: string | number; - method?: string; - params?: any; - result?: any; - error?: MCPError; -} -export interface MCPError { - code: number; - message: string; - data?: any; -} -export interface MCPTool { - name: string; - description: string; - inputSchema: { - type: 'object'; - properties: Record; - required: string[]; - additionalProperties?: boolean; - }; -} -export interface MCPResource { - uri: string; - name: string; - description?: string; - mimeType?: string; -} -export interface MCPPrompt { - name: string; - description?: string; - arguments?: Array<{ - name: string; - description?: string; - required?: boolean; - }>; -} -export interface MCPInitializeResult { - protocolVersion: string; - capabilities: { - tools?: {}; - resources?: {}; - prompts?: {}; - }; - serverInfo: { - name: string; - version: string; - }; -} diff --git a/build/cli/src/agent/reasoning/copilot/__tests__/copilot.test.d.ts b/build/cli/src/agent/reasoning/copilot/__tests__/copilot.test.d.ts deleted file mode 100644 index f9fc25ff..00000000 --- a/build/cli/src/agent/reasoning/copilot/__tests__/copilot.test.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Tests for Copilot Agent - */ -export {}; diff --git a/build/cli/src/agent/reasoning/copilot/agent_initializer.d.ts b/build/cli/src/agent/reasoning/copilot/agent_initializer.d.ts deleted file mode 100644 index 42d03e01..00000000 --- a/build/cli/src/agent/reasoning/copilot/agent_initializer.d.ts +++ /dev/null @@ -1,44 +0,0 @@ -/** - * Agent Initializer - * Initializes agent with tools and repository files for Copilot - */ -import { Agent } from '../../core/agent'; -import { CopilotOptions } from './types'; -import { ReadFileTool } from '../../tools/builtin_tools/read_file_tool'; -import { SearchFilesTool } from '../../tools/builtin_tools/search_files_tool'; -import { ProposeChangeTool } from '../../tools/builtin_tools/propose_change_tool'; -import { ApplyChangesTool } from '../../tools/builtin_tools/apply_changes_tool'; -import { ExecuteCommandTool } from '../../tools/builtin_tools/execute_command_tool'; -import { ManageTodosTool } from '../../tools/builtin_tools/manage_todos_tool'; -export interface AgentInitializerResult { - agent: Agent; - repositoryFiles: Map; -} -export declare class AgentInitializer { - private static readonly EXCLUDE_PATTERNS; - private static readonly IGNORE_FILES; - /** - * Initialize agent with tools and repository files - */ - static initialize(options: CopilotOptions): Promise; - /** - * Load repository files from GitHub - */ - private static loadRepositoryFiles; - /** - * Create tools for the agent - */ - static createTools(repositoryFiles: Map, options: CopilotOptions): Promise<(ReadFileTool | SearchFilesTool | ProposeChangeTool | ManageTodosTool | ApplyChangesTool | ExecuteCommandTool)[]>; - /** - * Create ManageTodosTool - */ - private static createManageTodosTool; - /** - * Search files in repository - */ - private static searchFiles; - /** - * Get all files (excluding compiled files) - */ - private static getAllFiles; -} diff --git a/build/cli/src/agent/reasoning/copilot/copilot.d.ts b/build/cli/src/agent/reasoning/copilot/copilot.d.ts deleted file mode 100644 index 717453ba..00000000 --- a/build/cli/src/agent/reasoning/copilot/copilot.d.ts +++ /dev/null @@ -1,62 +0,0 @@ -/** - * Copilot Agent - * Uses Agent SDK to provide advanced reasoning and code-manipulation capabilities - * - * Copilot can analyze, explain, answer questions about, and modify source code - * based on user-defined prompts or automated workflows. - * - * Its purpose is to act as an on-demand development assistant capable of offering - * guidance, insights, and direct code transformations across the repository. - */ -import { Agent } from '../../core/agent'; -import { CopilotOptions, CopilotResult } from './types'; -export declare class Copilot { - private agent; - private options; - private repositoryFiles; - private intentClassifier?; - constructor(options: CopilotOptions); - /** - * Process a user prompt and provide a response - * - * This method handles various types of requests: - * - Questions about code structure, functionality, or implementation - * - Requests to analyze code for issues or patterns - * - Requests to explain how code works - * - Requests to modify existing code - * - Requests to create new files or implement features - * - * @param prompt - User's prompt/question/request - * @returns CopilotResult containing the agent's response and any changes made - */ - processPrompt(prompt: string): Promise; - /** - * Determine if a prompt is complex enough to benefit from sub-agents - * - * @internal - * Complex prompts typically involve: - * - Analyzing multiple files - * - Refactoring across the codebase - * - Large-scale changes - * - Comprehensive analysis tasks - * - * @param prompt - User's prompt - * @returns true if the prompt seems complex - */ - private isComplexPrompt; - /** - * Extract changes from agent result - * - * @internal - * This method parses the agent's tool calls and results to identify any code changes - * that were proposed using the propose_change tool. - * - * @param result - Agent result containing tool calls and results - * @returns Array of changes made - */ - private extractChanges; - /** - * Get agent instance (for advanced usage) - */ - getAgent(): Agent; -} diff --git a/build/cli/src/agent/reasoning/copilot/file_partitioner.d.ts b/build/cli/src/agent/reasoning/copilot/file_partitioner.d.ts deleted file mode 100644 index b686830e..00000000 --- a/build/cli/src/agent/reasoning/copilot/file_partitioner.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -/** - * File Partitioner - * Partitions files by directory for subagent distribution - */ -export declare class FilePartitioner { - /** - * Partition files by directory to keep related files together - * Tries to balance file distribution across groups - */ - static partitionFilesByDirectory(files: string[], maxGroups: number): string[][]; -} diff --git a/build/cli/src/agent/reasoning/copilot/index.d.ts b/build/cli/src/agent/reasoning/copilot/index.d.ts deleted file mode 100644 index 19b9a86d..00000000 --- a/build/cli/src/agent/reasoning/copilot/index.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Copilot Agent Module - * Exports all public types and classes - */ -export { Copilot } from './copilot'; -export type { CopilotOptions, CopilotResult } from './types'; -export { SystemPromptBuilder } from './system_prompt_builder'; -export { AgentInitializer } from './agent_initializer'; -export { SubagentHandler } from './subagent_handler'; -export { FilePartitioner } from './file_partitioner'; diff --git a/build/cli/src/agent/reasoning/copilot/subagent_handler.d.ts b/build/cli/src/agent/reasoning/copilot/subagent_handler.d.ts deleted file mode 100644 index bcfcad9b..00000000 --- a/build/cli/src/agent/reasoning/copilot/subagent_handler.d.ts +++ /dev/null @@ -1,60 +0,0 @@ -/** - * Subagent Handler - * Handles Copilot tasks using subagents for parallel processing - */ -import { Agent } from '../../core/agent'; -import { CopilotOptions, CopilotResult } from './types'; -export declare class SubagentHandler { - private static readonly EXCLUDE_PATTERNS; - /** - * Process prompt using subagents for parallel processing - * - * Uses a two-phase approach: - * Phase 1: Subagents work in parallel (READ-ONLY) - analyze and propose changes - * Phase 2: Coordinator agent executes changes sequentially - */ - static processPromptWithSubAgents(agent: Agent, repositoryFiles: Map, options: CopilotOptions, userPrompt: string, shouldApplyChanges?: boolean): Promise; - /** - * Create READ-ONLY tools for subagents (Phase 1) - * Only allows reading files, searching, and proposing changes (in memory) - * Does NOT allow applying changes or executing commands - */ - private static createReadOnlySubagentTools; - /** - * Extract change plans from subagent results - */ - private static extractChangePlans; - /** - * Execute changes sequentially using coordinator agent (Phase 2) - */ - private static executeChangesSequentially; - /** - * Combine results from both phases - */ - private static combinePhasesResults; - /** - * Extract changes from agent result - */ - private static extractChangesFromResult; - /** - * Create tools for subagents (DEPRECATED - kept for backward compatibility) - * @deprecated Use createReadOnlySubagentTools for Phase 1 instead - */ - private static createSubagentTools; - /** - * Create ManageTodosTool - */ - private static createManageTodosTool; - /** - * Search files in repository - */ - private static searchFiles; - /** - * Get all files (excluding compiled files) - */ - private static getAllFiles; - /** - * Combine results from all subagents - */ - private static combineSubagentResults; -} diff --git a/build/cli/src/agent/reasoning/copilot/system_prompt_builder.d.ts b/build/cli/src/agent/reasoning/copilot/system_prompt_builder.d.ts deleted file mode 100644 index 5a796e45..00000000 --- a/build/cli/src/agent/reasoning/copilot/system_prompt_builder.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -/** - * System Prompt Builder - * Builds system prompts for Copilot agent - */ -import { CopilotOptions } from './types'; -export declare class SystemPromptBuilder { - /** - * Build system prompt for Copilot agent - */ - static build(options: CopilotOptions): string; -} diff --git a/build/cli/src/agent/reasoning/copilot/types.d.ts b/build/cli/src/agent/reasoning/copilot/types.d.ts deleted file mode 100644 index 62cd3cbb..00000000 --- a/build/cli/src/agent/reasoning/copilot/types.d.ts +++ /dev/null @@ -1,47 +0,0 @@ -/** - * Types and interfaces for Copilot Agent - */ -import { AgentResult } from '../../types'; -import { ChangeType } from '../../../data/model/think_response'; -/** - * Options for Copilot agent - */ -export interface CopilotOptions { - model?: string; - /** OpenCode server URL (e.g. http://localhost:4096) */ - serverUrl: string; - personalAccessToken?: string; - maxTurns?: number; - repositoryOwner?: string; - repositoryName?: string; - repositoryBranch?: string; - workingDirectory?: string; - useSubAgents?: boolean; - maxConcurrentSubAgents?: number; - userPrompt?: string; - useIntentClassifier?: boolean; - shouldApplyChanges?: boolean; -} -/** - * Change plan proposed by a subagent (Phase 1: Analysis) - */ -export interface ChangePlan { - file: string; - changeType: ChangeType; - description: string; - suggestedCode: string; - reasoning: string; - proposedBy: string; -} -/** - * Result of Copilot agent execution - */ -export interface CopilotResult { - response: string; - agentResult: AgentResult; - changes?: Array<{ - file: string; - changeType: ChangeType; - description?: string; - }>; -} diff --git a/build/cli/src/agent/reasoning/error_detector/__tests__/error_detector.test.d.ts b/build/cli/src/agent/reasoning/error_detector/__tests__/error_detector.test.d.ts deleted file mode 100644 index c2ed763b..00000000 --- a/build/cli/src/agent/reasoning/error_detector/__tests__/error_detector.test.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Tests for Error Detector - */ -export {}; diff --git a/build/cli/src/agent/reasoning/error_detector/__tests__/error_parser.test.d.ts b/build/cli/src/agent/reasoning/error_detector/__tests__/error_parser.test.d.ts deleted file mode 100644 index 887bab8a..00000000 --- a/build/cli/src/agent/reasoning/error_detector/__tests__/error_parser.test.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Tests for Error Parser - */ -export {}; diff --git a/build/cli/src/agent/reasoning/error_detector/__tests__/file_partitioner.test.d.ts b/build/cli/src/agent/reasoning/error_detector/__tests__/file_partitioner.test.d.ts deleted file mode 100644 index 42c32337..00000000 --- a/build/cli/src/agent/reasoning/error_detector/__tests__/file_partitioner.test.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Tests for File Partitioner - */ -export {}; diff --git a/build/cli/src/agent/reasoning/error_detector/__tests__/summary_generator.test.d.ts b/build/cli/src/agent/reasoning/error_detector/__tests__/summary_generator.test.d.ts deleted file mode 100644 index 37946029..00000000 --- a/build/cli/src/agent/reasoning/error_detector/__tests__/summary_generator.test.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Tests for Summary Generator - */ -export {}; diff --git a/build/cli/src/agent/reasoning/error_detector/__tests__/system_prompt_builder.test.d.ts b/build/cli/src/agent/reasoning/error_detector/__tests__/system_prompt_builder.test.d.ts deleted file mode 100644 index b913e9f8..00000000 --- a/build/cli/src/agent/reasoning/error_detector/__tests__/system_prompt_builder.test.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Tests for System Prompt Builder - */ -export {}; diff --git a/build/cli/src/agent/reasoning/error_detector/agent_initializer.d.ts b/build/cli/src/agent/reasoning/error_detector/agent_initializer.d.ts deleted file mode 100644 index 2bca7049..00000000 --- a/build/cli/src/agent/reasoning/error_detector/agent_initializer.d.ts +++ /dev/null @@ -1,45 +0,0 @@ -/** - * Agent Initializer - * Initializes agent with tools and repository files - */ -import { Agent } from '../../core/agent'; -import { ErrorDetectionOptions } from './types'; -import { ReadFileTool } from '../../tools/builtin_tools/read_file_tool'; -import { SearchFilesTool } from '../../tools/builtin_tools/search_files_tool'; -import { ProposeChangeTool } from '../../tools/builtin_tools/propose_change_tool'; -import { ManageTodosTool } from '../../tools/builtin_tools/manage_todos_tool'; -import { ReportErrorsTool } from '../../tools/builtin_tools/report_errors_tool'; -import { DetectedError } from './types'; -export interface AgentInitializerResult { - agent: Agent; - repositoryFiles: Map; - reportedErrors: DetectedError[]; -} -export declare class AgentInitializer { - private static readonly EXCLUDE_PATTERNS; - private static readonly IGNORE_FILES; - /** - * Initialize agent with tools and repository files - */ - static initialize(options: ErrorDetectionOptions): Promise; - /** - * Load repository files from GitHub - */ - private static loadRepositoryFiles; - /** - * Create tools for the agent - */ - static createTools(repositoryFiles: Map, onErrorsReported?: (errors: DetectedError[]) => void): Promise<(ReadFileTool | SearchFilesTool | ProposeChangeTool | ManageTodosTool | ReportErrorsTool)[]>; - /** - * Create ManageTodosTool - */ - private static createManageTodosTool; - /** - * Search files in repository - */ - private static searchFiles; - /** - * Get all files (excluding compiled files) - */ - private static getAllFiles; -} diff --git a/build/cli/src/agent/reasoning/error_detector/error_detector.d.ts b/build/cli/src/agent/reasoning/error_detector/error_detector.d.ts deleted file mode 100644 index 3c61ba52..00000000 --- a/build/cli/src/agent/reasoning/error_detector/error_detector.d.ts +++ /dev/null @@ -1,20 +0,0 @@ -/** - * Error Detector - * Uses Agent SDK to detect potential errors in the codebase - */ -import { Agent } from '../../core/agent'; -import { ErrorDetectionOptions, ErrorDetectionResult } from './types'; -export declare class ErrorDetector { - private agent; - private options; - private repositoryFiles; - constructor(options: ErrorDetectionOptions); - /** - * Detect errors in the codebase - */ - detectErrors(prompt?: string): Promise; - /** - * Get agent instance (for advanced usage) - */ - getAgent(): Agent; -} diff --git a/build/cli/src/agent/reasoning/error_detector/error_parser.d.ts b/build/cli/src/agent/reasoning/error_detector/error_parser.d.ts deleted file mode 100644 index 314e8a4e..00000000 --- a/build/cli/src/agent/reasoning/error_detector/error_parser.d.ts +++ /dev/null @@ -1,14 +0,0 @@ -/** - * Error Parser - * Parses errors from agent results and tool calls - */ -import { AgentResult } from '../../types'; -import { DetectedError } from './types'; -export declare class ErrorParser { - /** - * Parse errors from agent result - * Only uses structured format from report_errors tool - no text parsing - * The tool already validates and cleans the data, so we just extract it directly - */ - static parseErrors(result: AgentResult): DetectedError[]; -} diff --git a/build/cli/src/agent/reasoning/error_detector/file_partitioner.d.ts b/build/cli/src/agent/reasoning/error_detector/file_partitioner.d.ts deleted file mode 100644 index b686830e..00000000 --- a/build/cli/src/agent/reasoning/error_detector/file_partitioner.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -/** - * File Partitioner - * Partitions files by directory for subagent distribution - */ -export declare class FilePartitioner { - /** - * Partition files by directory to keep related files together - * Tries to balance file distribution across groups - */ - static partitionFilesByDirectory(files: string[], maxGroups: number): string[][]; -} diff --git a/build/cli/src/agent/reasoning/error_detector/file_relationship_analyzer.d.ts b/build/cli/src/agent/reasoning/error_detector/file_relationship_analyzer.d.ts deleted file mode 100644 index 75ef4335..00000000 --- a/build/cli/src/agent/reasoning/error_detector/file_relationship_analyzer.d.ts +++ /dev/null @@ -1,18 +0,0 @@ -/** - * File Relationship Analyzer - * Analyzes file relationships and finds consumers/dependencies - */ -export interface FileRelationshipResult { - targetFile: string; - consumers: string[]; - dependencies: string[]; - allRelatedFiles: string[]; -} -export declare class FileRelationshipAnalyzer { - private fileImportAnalyzer; - constructor(); - /** - * Analyze relationships for a target file - */ - analyzeFileRelationships(targetFile: string, repositoryFiles: Map, includeDependencies?: boolean): FileRelationshipResult | null; -} diff --git a/build/cli/src/agent/reasoning/error_detector/index.d.ts b/build/cli/src/agent/reasoning/error_detector/index.d.ts deleted file mode 100644 index 1b355cc4..00000000 --- a/build/cli/src/agent/reasoning/error_detector/index.d.ts +++ /dev/null @@ -1,13 +0,0 @@ -/** - * Error Detector Module - * Exports all public types and classes - */ -export { ErrorDetector } from './error_detector'; -export type { ErrorDetectionOptions, DetectedError, ErrorDetectionResult } from './types'; -export { ErrorParser } from './error_parser'; -export { SummaryGenerator } from './summary_generator'; -export { FilePartitioner } from './file_partitioner'; -export { SystemPromptBuilder } from './system_prompt_builder'; -export { AgentInitializer } from './agent_initializer'; -export { SubagentHandler } from './subagent_handler'; -export { FileRelationshipAnalyzer } from './file_relationship_analyzer'; diff --git a/build/cli/src/agent/reasoning/error_detector/subagent_handler.d.ts b/build/cli/src/agent/reasoning/error_detector/subagent_handler.d.ts deleted file mode 100644 index 66821ad3..00000000 --- a/build/cli/src/agent/reasoning/error_detector/subagent_handler.d.ts +++ /dev/null @@ -1,29 +0,0 @@ -/** - * Subagent Handler - * Handles error detection using subagents for parallel processing - */ -import { Agent } from '../../core/agent'; -import { ErrorDetectionOptions, ErrorDetectionResult } from './types'; -export declare class SubagentHandler { - private static readonly EXCLUDE_PATTERNS; - /** - * Detect errors using subagents for parallel processing - */ - static detectErrorsWithSubAgents(agent: Agent, repositoryFiles: Map, options: ErrorDetectionOptions, userPrompt: string): Promise; - /** - * Create tools for subagents - */ - private static createSubagentTools; - /** - * Search files in repository - */ - private static searchFiles; - /** - * Get all files (excluding compiled files) - */ - private static getAllFiles; - /** - * Combine results from all subagents - */ - private static combineSubagentResults; -} diff --git a/build/cli/src/agent/reasoning/error_detector/summary_generator.d.ts b/build/cli/src/agent/reasoning/error_detector/summary_generator.d.ts deleted file mode 100644 index f14e553a..00000000 --- a/build/cli/src/agent/reasoning/error_detector/summary_generator.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -/** - * Summary Generator - * Generates summaries of detected errors - */ -import { DetectedError, ErrorDetectionResult } from './types'; -export declare class SummaryGenerator { - /** - * Generate summary of detected errors - */ - static generateSummary(errors: DetectedError[]): ErrorDetectionResult['summary']; -} diff --git a/build/cli/src/agent/reasoning/error_detector/system_prompt_builder.d.ts b/build/cli/src/agent/reasoning/error_detector/system_prompt_builder.d.ts deleted file mode 100644 index 633fff5a..00000000 --- a/build/cli/src/agent/reasoning/error_detector/system_prompt_builder.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -/** - * System Prompt Builder - * Builds system prompts for error detection - */ -import { ErrorDetectionOptions } from './types'; -export declare class SystemPromptBuilder { - /** - * Build system prompt for error detection - */ - static build(options: ErrorDetectionOptions): string; -} diff --git a/build/cli/src/agent/reasoning/error_detector/types.d.ts b/build/cli/src/agent/reasoning/error_detector/types.d.ts deleted file mode 100644 index f801a35f..00000000 --- a/build/cli/src/agent/reasoning/error_detector/types.d.ts +++ /dev/null @@ -1,117 +0,0 @@ -/** - * Types and interfaces for Error Detector - */ -import { AgentResult } from '../../types'; -/** - * Standard issue types for code analysis - * Based on common industry standards (SonarQube, ESLint, PMD, CWE, OWASP) - */ -export declare enum IssueType { - BUG = "bug", - LOGIC_ERROR = "logic-error", - RUNTIME_ERROR = "runtime-error", - NULL_POINTER = "null-pointer", - ARRAY_BOUNDS = "array-bounds", - DIVISION_BY_ZERO = "division-by-zero", - TYPE_ERROR = "type-error", - TYPE_MISMATCH = "type-mismatch", - SECURITY_VULNERABILITY = "security-vulnerability", - SQL_INJECTION = "sql-injection", - COMMAND_INJECTION = "command-injection", - XSS = "xss", - CSRF = "csrf", - AUTHENTICATION_BYPASS = "authentication-bypass", - AUTHORIZATION_BYPASS = "authorization-bypass", - SENSITIVE_DATA_EXPOSURE = "sensitive-data-exposure", - INSECURE_DESERIALIZATION = "insecure-deserialization", - SSRF = "ssrf", - BUFFER_OVERFLOW = "buffer-overflow", - INSECURE_CRYPTO = "insecure-crypto", - WEAK_RANDOM = "weak-random", - HARDCODED_SECRET = "hardcoded-secret", - INSECURE_DEPENDENCY = "insecure-dependency", - PERFORMANCE_ISSUE = "performance-issue", - MEMORY_LEAK = "memory-leak", - RESOURCE_LEAK = "resource-leak", - INEFFICIENT_ALGORITHM = "inefficient-algorithm", - UNNECESSARY_COMPUTATION = "unnecessary-computation", - BLOCKING_OPERATION = "blocking-operation", - CODE_SMELL = "code-smell", - DEAD_CODE = "dead-code", - DUPLICATE_CODE = "duplicate-code", - HIGH_COMPLEXITY = "high-complexity", - CYCLOMATIC_COMPLEXITY = "cyclomatic-complexity", - LONG_METHOD = "long-method", - LONG_PARAMETER_LIST = "long-parameter-list", - GOD_CLASS = "god-class", - MAGIC_NUMBER = "magic-number", - MISSING_ERROR_HANDLING = "missing-error-handling", - EMPTY_CATCH_BLOCK = "empty-catch-block", - CONFIGURATION_ERROR = "configuration-error", - MISCONFIGURATION = "misconfiguration", - MISSING_CONFIGURATION = "missing-configuration", - INVALID_CONFIGURATION = "invalid-configuration", - EXPOSED_CREDENTIALS = "exposed-credentials", - INSECURE_PERMISSIONS = "insecure-permissions", - RACE_CONDITION = "race-condition", - DEADLOCK = "deadlock", - THREAD_SAFETY = "thread-safety", - UNSAFE_CONCURRENCY = "unsafe-concurrency", - DEPRECATED_API = "deprecated-api", - UNUSED_CODE = "unused-code", - UNUSED_IMPORT = "unused-import", - UNUSED_VARIABLE = "unused-variable", - UNUSED_PARAMETER = "unused-parameter", - BEST_PRACTICE_VIOLATION = "best-practice-violation", - CODING_STANDARD_VIOLATION = "coding-standard-violation", - NAMING_CONVENTION = "naming-convention", - CODE_STYLE = "code-style", - CODE_ISSUE = "code-issue" -} -/** - * Severity levels for detected errors - */ -export declare enum SeverityLevel { - CRITICAL = "critical", - HIGH = "high", - MEDIUM = "medium", - LOW = "low" -} -export interface ErrorDetectionOptions { - model?: string; - serverUrl: string; - personalAccessToken?: string; - maxTurns?: number; - repositoryOwner?: string; - repositoryName?: string; - repositoryBranch?: string; - focusAreas?: string[]; - errorTypes?: IssueType[]; - useSubAgents?: boolean; - maxConcurrentSubAgents?: number; - targetFile?: string; - analyzeOnlyTargetFile?: boolean; - includeDependencies?: boolean; -} -export interface DetectedError { - file: string; - line?: number; - type: IssueType; - severity: SeverityLevel; - description: string; - suggestion?: string; -} -export interface ErrorDetectionResult { - errors: DetectedError[]; - summary: { - total: number; - bySeverity: { - critical: number; - high: number; - medium: number; - low: number; - }; - byType: Record; - }; - agentResult: AgentResult; -} diff --git a/build/cli/src/agent/reasoning/intent_classifier/__tests__/intent_classifier.test.d.ts b/build/cli/src/agent/reasoning/intent_classifier/__tests__/intent_classifier.test.d.ts deleted file mode 100644 index ce169c4a..00000000 --- a/build/cli/src/agent/reasoning/intent_classifier/__tests__/intent_classifier.test.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Tests for Intent Classifier Agent - */ -export {}; diff --git a/build/cli/src/agent/reasoning/intent_classifier/agent_initializer.d.ts b/build/cli/src/agent/reasoning/intent_classifier/agent_initializer.d.ts deleted file mode 100644 index 2c7d8921..00000000 --- a/build/cli/src/agent/reasoning/intent_classifier/agent_initializer.d.ts +++ /dev/null @@ -1,24 +0,0 @@ -/** - * Agent Initializer - * Initializes agent with tools for Intent Classifier - */ -import { Agent } from '../../core/agent'; -import { IntentClassifierOptions, ConfidenceLevel } from './types'; -export interface AgentInitializerResult { - agent: Agent; - reportedIntent?: { - shouldApplyChanges: boolean; - reasoning: string; - confidence: ConfidenceLevel; - }; -} -export declare class AgentInitializer { - /** - * Initialize agent with tools - */ - static initialize(options: IntentClassifierOptions): Promise; - /** - * Create tools for the agent - */ - private static createTools; -} diff --git a/build/cli/src/agent/reasoning/intent_classifier/index.d.ts b/build/cli/src/agent/reasoning/intent_classifier/index.d.ts deleted file mode 100644 index b2b76e61..00000000 --- a/build/cli/src/agent/reasoning/intent_classifier/index.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -/** - * Intent Classifier Agent - * Exports for intent classification - */ -export { IntentClassifier } from './intent_classifier'; -export { IntentClassifierOptions, IntentClassificationResult } from './types'; -export { SystemPromptBuilder } from './system_prompt_builder'; -export { IntentParser } from './intent_parser'; -export { AgentInitializer } from './agent_initializer'; diff --git a/build/cli/src/agent/reasoning/intent_classifier/intent_classifier.d.ts b/build/cli/src/agent/reasoning/intent_classifier/intent_classifier.d.ts deleted file mode 100644 index 86a4d148..00000000 --- a/build/cli/src/agent/reasoning/intent_classifier/intent_classifier.d.ts +++ /dev/null @@ -1,21 +0,0 @@ -/** - * Intent Classifier Agent - * Classifies user prompts to determine if changes should be applied to disk or kept in memory - */ -import { IntentClassifierOptions, IntentClassificationResult } from './types'; -export declare class IntentClassifier { - private agent; - private options; - constructor(options: IntentClassifierOptions); - /** - * Classify user prompt to determine if changes should be applied - * @param prompt - User prompt to classify - * @returns IntentClassificationResult indicating if changes should be applied - */ - classifyIntent(prompt: string): Promise; - /** - * Fallback classification using simple heuristics if agent fails - * This is used when the parser cannot extract valid JSON from the response - */ - private fallbackClassification; -} diff --git a/build/cli/src/agent/reasoning/intent_classifier/intent_parser.d.ts b/build/cli/src/agent/reasoning/intent_classifier/intent_parser.d.ts deleted file mode 100644 index 7f90f325..00000000 --- a/build/cli/src/agent/reasoning/intent_classifier/intent_parser.d.ts +++ /dev/null @@ -1,15 +0,0 @@ -/** - * Intent Parser - * Parses intent classification from agent results - * Only uses structured format from report_intent tool - no text parsing - */ -import { AgentResult } from '../../types'; -import { IntentClassificationResult } from './types'; -export declare class IntentParser { - /** - * Parse intent classification from agent result - * Only uses structured format from report_intent tool - no text parsing - * The tool already validates and cleans the data, so we just extract it directly - */ - static parseIntent(result: AgentResult): IntentClassificationResult; -} diff --git a/build/cli/src/agent/reasoning/intent_classifier/system_prompt_builder.d.ts b/build/cli/src/agent/reasoning/intent_classifier/system_prompt_builder.d.ts deleted file mode 100644 index 9fbc6409..00000000 --- a/build/cli/src/agent/reasoning/intent_classifier/system_prompt_builder.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -/** - * System Prompt Builder for Intent Classifier - */ -export declare class SystemPromptBuilder { - static build(): string; -} diff --git a/build/cli/src/agent/reasoning/intent_classifier/types.d.ts b/build/cli/src/agent/reasoning/intent_classifier/types.d.ts deleted file mode 100644 index 68069a44..00000000 --- a/build/cli/src/agent/reasoning/intent_classifier/types.d.ts +++ /dev/null @@ -1,20 +0,0 @@ -/** - * Types for Intent Classifier Agent - */ -import { AgentResult } from '../../types'; -export declare enum ConfidenceLevel { - HIGH = "high", - MEDIUM = "medium", - LOW = "low" -} -export interface IntentClassifierOptions { - model?: string; - serverUrl: string; - maxTurns?: number; -} -export interface IntentClassificationResult { - shouldApplyChanges: boolean; - reasoning: string; - confidence: ConfidenceLevel; - agentResult: AgentResult; -} diff --git a/build/cli/src/agent/reasoning/progress_detector/__tests__/file_partitioner.test.d.ts b/build/cli/src/agent/reasoning/progress_detector/__tests__/file_partitioner.test.d.ts deleted file mode 100644 index 42c32337..00000000 --- a/build/cli/src/agent/reasoning/progress_detector/__tests__/file_partitioner.test.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Tests for File Partitioner - */ -export {}; diff --git a/build/cli/src/agent/reasoning/progress_detector/__tests__/progress_detector.test.d.ts b/build/cli/src/agent/reasoning/progress_detector/__tests__/progress_detector.test.d.ts deleted file mode 100644 index 81f87b46..00000000 --- a/build/cli/src/agent/reasoning/progress_detector/__tests__/progress_detector.test.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Tests for Progress Detector - */ -export {}; diff --git a/build/cli/src/agent/reasoning/progress_detector/__tests__/progress_parser.test.d.ts b/build/cli/src/agent/reasoning/progress_detector/__tests__/progress_parser.test.d.ts deleted file mode 100644 index 5e00815d..00000000 --- a/build/cli/src/agent/reasoning/progress_detector/__tests__/progress_parser.test.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Tests for Progress Parser - */ -export {}; diff --git a/build/cli/src/agent/reasoning/progress_detector/__tests__/subagent_handler.test.d.ts b/build/cli/src/agent/reasoning/progress_detector/__tests__/subagent_handler.test.d.ts deleted file mode 100644 index da6a2d27..00000000 --- a/build/cli/src/agent/reasoning/progress_detector/__tests__/subagent_handler.test.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Tests for Subagent Handler - */ -export {}; diff --git a/build/cli/src/agent/reasoning/progress_detector/__tests__/system_prompt_builder.test.d.ts b/build/cli/src/agent/reasoning/progress_detector/__tests__/system_prompt_builder.test.d.ts deleted file mode 100644 index b913e9f8..00000000 --- a/build/cli/src/agent/reasoning/progress_detector/__tests__/system_prompt_builder.test.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Tests for System Prompt Builder - */ -export {}; diff --git a/build/cli/src/agent/reasoning/progress_detector/agent_initializer.d.ts b/build/cli/src/agent/reasoning/progress_detector/agent_initializer.d.ts deleted file mode 100644 index 777ed6f0..00000000 --- a/build/cli/src/agent/reasoning/progress_detector/agent_initializer.d.ts +++ /dev/null @@ -1,42 +0,0 @@ -/** - * Agent Initializer - * Initializes agent with tools and repository files for progress detection - */ -import { Agent } from '../../core/agent'; -import { ProgressDetectionOptions } from './types'; -import { ReadFileTool } from '../../tools/builtin_tools/read_file_tool'; -import { SearchFilesTool } from '../../tools/builtin_tools/search_files_tool'; -import { ReportProgressTool } from '../../tools/builtin_tools/report_progress_tool'; -export interface AgentInitializerResult { - agent: Agent; - repositoryFiles: Map; - reportedProgress?: { - progress: number; - summary: string; - }; -} -export declare class AgentInitializer { - private static readonly EXCLUDE_PATTERNS; - private static readonly IGNORE_FILES; - /** - * Initialize agent with tools and repository files - */ - static initialize(options: ProgressDetectionOptions): Promise; - /** - * Load repository files from GitHub - * Only loads changed files if available, otherwise loads all files from the branch - */ - private static loadRepositoryFiles; - /** - * Create tools for the agent - */ - static createTools(repositoryFiles: Map, onProgressReported?: (progress: number, summary: string) => void): Promise<(ReadFileTool | SearchFilesTool | ReportProgressTool)[]>; - /** - * Search files in repository - */ - private static searchFiles; - /** - * Get all files (excluding compiled files) - */ - private static getAllFiles; -} diff --git a/build/cli/src/agent/reasoning/progress_detector/file_partitioner.d.ts b/build/cli/src/agent/reasoning/progress_detector/file_partitioner.d.ts deleted file mode 100644 index b686830e..00000000 --- a/build/cli/src/agent/reasoning/progress_detector/file_partitioner.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -/** - * File Partitioner - * Partitions files by directory for subagent distribution - */ -export declare class FilePartitioner { - /** - * Partition files by directory to keep related files together - * Tries to balance file distribution across groups - */ - static partitionFilesByDirectory(files: string[], maxGroups: number): string[][]; -} diff --git a/build/cli/src/agent/reasoning/progress_detector/index.d.ts b/build/cli/src/agent/reasoning/progress_detector/index.d.ts deleted file mode 100644 index 269275c8..00000000 --- a/build/cli/src/agent/reasoning/progress_detector/index.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -/** - * Progress Detector Module - * Exports all public types and classes - */ -export { ProgressDetector } from './progress_detector'; -export type { ProgressDetectionOptions, ProgressDetectionResult } from './types'; -export { ProgressParser } from './progress_parser'; -export { SystemPromptBuilder } from './system_prompt_builder'; -export { AgentInitializer } from './agent_initializer'; -export { SubagentHandler } from './subagent_handler'; -export { FilePartitioner } from './file_partitioner'; diff --git a/build/cli/src/agent/reasoning/progress_detector/progress_detector.d.ts b/build/cli/src/agent/reasoning/progress_detector/progress_detector.d.ts deleted file mode 100644 index 71985369..00000000 --- a/build/cli/src/agent/reasoning/progress_detector/progress_detector.d.ts +++ /dev/null @@ -1,20 +0,0 @@ -/** - * Progress Detector - * Uses Agent SDK to detect progress of a task based on code changes - */ -import { Agent } from '../../core/agent'; -import { ProgressDetectionOptions, ProgressDetectionResult } from './types'; -export declare class ProgressDetector { - private agent; - private options; - private repositoryFiles; - constructor(options: ProgressDetectionOptions); - /** - * Detect progress of the task - */ - detectProgress(prompt?: string): Promise; - /** - * Get agent instance (for advanced usage) - */ - getAgent(): Agent; -} diff --git a/build/cli/src/agent/reasoning/progress_detector/progress_parser.d.ts b/build/cli/src/agent/reasoning/progress_detector/progress_parser.d.ts deleted file mode 100644 index 9d52facd..00000000 --- a/build/cli/src/agent/reasoning/progress_detector/progress_parser.d.ts +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Progress Parser - * Parses progress percentage from agent results - * Only uses structured format from report_progress tool - no text parsing - */ -import { AgentResult } from '../../types'; -export declare class ProgressParser { - /** - * Parse progress from agent result - * Only uses structured format from report_progress tool - no text parsing - * The tool already validates and cleans the data, so we just extract it directly - */ - static parseProgress(result: AgentResult): { - progress: number; - summary: string; - }; -} diff --git a/build/cli/src/agent/reasoning/progress_detector/subagent_handler.d.ts b/build/cli/src/agent/reasoning/progress_detector/subagent_handler.d.ts deleted file mode 100644 index 8fb56921..00000000 --- a/build/cli/src/agent/reasoning/progress_detector/subagent_handler.d.ts +++ /dev/null @@ -1,30 +0,0 @@ -/** - * Subagent Handler - * Handles progress detection using subagents for parallel processing - */ -import { Agent } from '../../core/agent'; -import { ProgressDetectionOptions, ProgressDetectionResult } from './types'; -export declare class SubagentHandler { - private static readonly EXCLUDE_PATTERNS; - /** - * Detect progress using subagents for parallel processing - */ - static detectProgressWithSubAgents(agent: Agent, repositoryFiles: Map, options: ProgressDetectionOptions, userPrompt: string): Promise; - /** - * Create tools for subagents - */ - private static createSubagentTools; - /** - * Search files in repository - */ - private static searchFiles; - /** - * Get all files (excluding compiled files) - */ - private static getAllFiles; - /** - * Combine results from all subagents - * Calculates average progress and combines summaries - */ - private static combineSubagentResults; -} diff --git a/build/cli/src/agent/reasoning/progress_detector/system_prompt_builder.d.ts b/build/cli/src/agent/reasoning/progress_detector/system_prompt_builder.d.ts deleted file mode 100644 index 65358f31..00000000 --- a/build/cli/src/agent/reasoning/progress_detector/system_prompt_builder.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -/** - * System Prompt Builder - * Builds system prompts for progress detection - */ -import { ProgressDetectionOptions } from './types'; -export declare class SystemPromptBuilder { - /** - * Build system prompt for progress detection - */ - static build(options: ProgressDetectionOptions): string; -} diff --git a/build/cli/src/agent/reasoning/progress_detector/types.d.ts b/build/cli/src/agent/reasoning/progress_detector/types.d.ts deleted file mode 100644 index 8a07fa10..00000000 --- a/build/cli/src/agent/reasoning/progress_detector/types.d.ts +++ /dev/null @@ -1,36 +0,0 @@ -/** - * Types and interfaces for Progress Detector - */ -import { AgentResult } from '../../types'; -/** - * Options for progress detection - */ -export interface ProgressDetectionOptions { - model?: string; - serverUrl: string; - personalAccessToken?: string; - maxTurns?: number; - repositoryOwner?: string; - repositoryName?: string; - repositoryBranch?: string; - developmentBranch?: string; - issueNumber?: number; - issueDescription?: string; - changedFiles?: Array<{ - filename: string; - status: 'added' | 'modified' | 'removed' | 'renamed'; - additions?: number; - deletions?: number; - patch?: string; - }>; - useSubAgents?: boolean; - maxConcurrentSubAgents?: number; -} -/** - * Result of progress detection - */ -export interface ProgressDetectionResult { - progress: number; - summary: string; - agentResult: AgentResult; -} diff --git a/build/cli/src/agent/tools/base_tool.d.ts b/build/cli/src/agent/tools/base_tool.d.ts deleted file mode 100644 index 2b0ca2d2..00000000 --- a/build/cli/src/agent/tools/base_tool.d.ts +++ /dev/null @@ -1,42 +0,0 @@ -/** - * Base class for all tools - */ -import { ToolDefinition, ToolExecutionResult } from '../types'; -export declare abstract class BaseTool { - /** - * Get tool name - */ - abstract getName(): string; - /** - * Get tool description - */ - abstract getDescription(): string; - /** - * Get input schema (JSON Schema format) - */ - abstract getInputSchema(): { - type: 'object'; - properties: Record; - required: string[]; - additionalProperties?: boolean; - }; - /** - * Execute the tool - */ - abstract execute(input: Record): Promise; - /** - * Get tool definition - */ - getDefinition(): ToolDefinition; - /** - * Validate input against schema - */ - validateInput(input: Record): { - valid: boolean; - error?: string; - }; - /** - * Execute with validation - */ - executeWithValidation(input: Record): Promise; -} diff --git a/build/cli/src/agent/tools/builtin_tools/__tests__/apply_changes_tool.test.d.ts b/build/cli/src/agent/tools/builtin_tools/__tests__/apply_changes_tool.test.d.ts deleted file mode 100644 index 45e39211..00000000 --- a/build/cli/src/agent/tools/builtin_tools/__tests__/apply_changes_tool.test.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Tests for Apply Changes Tool - */ -export {}; diff --git a/build/cli/src/agent/tools/builtin_tools/__tests__/execute_command_tool.test.d.ts b/build/cli/src/agent/tools/builtin_tools/__tests__/execute_command_tool.test.d.ts deleted file mode 100644 index e5ddd49c..00000000 --- a/build/cli/src/agent/tools/builtin_tools/__tests__/execute_command_tool.test.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Tests for Execute Command Tool - */ -export {}; diff --git a/build/cli/src/agent/tools/builtin_tools/__tests__/manage_todos_tool.test.d.ts b/build/cli/src/agent/tools/builtin_tools/__tests__/manage_todos_tool.test.d.ts deleted file mode 100644 index 5d3b4977..00000000 --- a/build/cli/src/agent/tools/builtin_tools/__tests__/manage_todos_tool.test.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Tests for Manage TODOs Tool - */ -export {}; diff --git a/build/cli/src/agent/tools/builtin_tools/__tests__/propose_change_tool.test.d.ts b/build/cli/src/agent/tools/builtin_tools/__tests__/propose_change_tool.test.d.ts deleted file mode 100644 index 66952c98..00000000 --- a/build/cli/src/agent/tools/builtin_tools/__tests__/propose_change_tool.test.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Tests for Propose Change Tool - */ -export {}; diff --git a/build/cli/src/agent/tools/builtin_tools/__tests__/read_file_tool.test.d.ts b/build/cli/src/agent/tools/builtin_tools/__tests__/read_file_tool.test.d.ts deleted file mode 100644 index 30538889..00000000 --- a/build/cli/src/agent/tools/builtin_tools/__tests__/read_file_tool.test.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Tests for Read File Tool - */ -export {}; diff --git a/build/cli/src/agent/tools/builtin_tools/__tests__/report_errors_tool.test.d.ts b/build/cli/src/agent/tools/builtin_tools/__tests__/report_errors_tool.test.d.ts deleted file mode 100644 index e9c9cd30..00000000 --- a/build/cli/src/agent/tools/builtin_tools/__tests__/report_errors_tool.test.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Tests for Report Errors Tool - */ -export {}; diff --git a/build/cli/src/agent/tools/builtin_tools/__tests__/report_intent_tool.test.d.ts b/build/cli/src/agent/tools/builtin_tools/__tests__/report_intent_tool.test.d.ts deleted file mode 100644 index 6c85aec8..00000000 --- a/build/cli/src/agent/tools/builtin_tools/__tests__/report_intent_tool.test.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Tests for Report Intent Tool - */ -export {}; diff --git a/build/cli/src/agent/tools/builtin_tools/__tests__/report_progress_tool.test.d.ts b/build/cli/src/agent/tools/builtin_tools/__tests__/report_progress_tool.test.d.ts deleted file mode 100644 index fbe4547a..00000000 --- a/build/cli/src/agent/tools/builtin_tools/__tests__/report_progress_tool.test.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Tests for Report Progress Tool - */ -export {}; diff --git a/build/cli/src/agent/tools/builtin_tools/__tests__/search_files_tool.test.d.ts b/build/cli/src/agent/tools/builtin_tools/__tests__/search_files_tool.test.d.ts deleted file mode 100644 index 25f9bda2..00000000 --- a/build/cli/src/agent/tools/builtin_tools/__tests__/search_files_tool.test.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Tests for Search Files Tool - */ -export {}; diff --git a/build/cli/src/agent/tools/builtin_tools/apply_changes_tool.d.ts b/build/cli/src/agent/tools/builtin_tools/apply_changes_tool.d.ts deleted file mode 100644 index 70d5dd1d..00000000 --- a/build/cli/src/agent/tools/builtin_tools/apply_changes_tool.d.ts +++ /dev/null @@ -1,170 +0,0 @@ -/** - * Apply Changes Tool - Applies proposed changes from the virtual codebase to the actual file system. - * - * This tool writes files from the virtual codebase (in-memory changes) to the actual file system. - * It only applies changes to files within the working directory for safety, preventing accidental - * modifications outside the project scope. - * - * @internal - * This tool is used after propose_change to write changes to disk. It supports both specific - * file paths and applying all pending changes. The tool includes safety checks to ensure files - * are within the working directory and handles directory creation automatically. - * - * @remarks - * - Only applies changes to files within the working directory (safety check) - * - Supports dry-run mode to preview changes without writing to disk - * - Automatically creates directories if they don't exist - * - Can apply specific files or all pending changes - * - Returns detailed summary of applied changes and any errors - * - * @example - * ```typescript - * const tool = new ApplyChangesTool({ - * getVirtualCodebase: () => new Map([['src/utils.ts', 'export function util() {}']]), - * getWorkingDirectory: () => '/project', - * onChangesApplied: (changes) => { console.log('Applied:', changes); } - * }); - * - * // Apply all pending changes - * await tool.execute({}); - * - * // Apply specific files - * await tool.execute({ file_paths: ['src/utils.ts'] }); - * - * // Dry run - * await tool.execute({ dry_run: true }); - * ``` - */ -import { BaseTool } from '../base_tool'; -/** - * Options for configuring the ApplyChangesTool. - * - * @internal - * These callbacks connect the tool to the virtual codebase and working directory management. - * - * @property getVirtualCodebase - Callback to get the virtual codebase Map (file path -> content). - * @property getWorkingDirectory - Callback to get the working directory path. - * @property onChangesApplied - Optional callback invoked when changes are successfully applied to disk. - */ -export interface ApplyChangesToolOptions { - /** - * Gets the virtual codebase Map. - * - * @internal - * This callback returns the in-memory virtual codebase containing files that have been - * modified via propose_change but not yet written to disk. - * - * @returns Map of file paths to their contents - */ - getVirtualCodebase: () => Map; - /** - * Gets the working directory path. - * - * @internal - * This callback returns the working directory where files should be written. Only files - * within this directory will be applied (safety check). - * - * @returns Working directory path - */ - getWorkingDirectory: () => string; - /** - * Optional callback invoked when changes are successfully applied. - * - * @internal - * This callback is invoked after changes are written to disk (not during dry-run). - * It receives an array of applied changes with file paths and change types. - * - * @param changes - Array of applied changes with file path and change type - */ - onChangesApplied?: (changes: Array<{ - file: string; - changeType: string; - }>) => void; -} -/** - * ApplyChangesTool - Tool for applying proposed changes from virtual codebase to file system. - * - * This tool provides a safe way to write files from the virtual codebase to disk. It includes - * safety checks to ensure files are within the working directory and supports dry-run mode. - * - * @internal - * The tool validates file paths, creates directories as needed, and handles errors gracefully. - * It only applies changes to files within the working directory to prevent accidental - * modifications outside the project scope. - */ -export declare class ApplyChangesTool extends BaseTool { - private options; - /** - * Creates a new ApplyChangesTool instance. - * - * @internal - * The options parameter provides callbacks that connect this tool to the virtual codebase - * and working directory management. - * - * @param options - Configuration object with callbacks for file operations - */ - constructor(options: ApplyChangesToolOptions); - /** - * Returns the tool name used by the agent system. - * - * @internal - * This name is used when the agent calls the tool via tool calls. - * - * @returns Tool identifier: 'apply_changes' - */ - getName(): string; - /** - * Returns the tool description shown to the agent. - * - * @internal - * This description helps the agent understand when and how to use this tool. - * It's included in the agent's available tools list. - * - * @returns Human-readable description of the tool's purpose - */ - getDescription(): string; - getInputSchema(): { - type: 'object'; - properties: Record; - required: string[]; - additionalProperties?: boolean; - }; - /** - * Executes the tool with the provided input. - * - * This method applies files from the virtual codebase to the file system. It supports - * applying specific files or all pending changes, and includes a dry-run mode for preview. - * - * @internal - * The method performs the following steps: - * 1. Determines which files to apply (specific files or all pending changes) - * 2. Filters files to only include those within the working directory (safety check) - * 3. For each file: creates directory if needed, writes file content, or previews in dry-run - * 4. Collects errors and returns summary of applied changes - * - * @param input - Tool input containing optional file_paths array and dry_run boolean - * @returns String response with summary of applied changes and any errors - * - * @remarks - * - Files outside the working directory are skipped with a warning - * - Directories are created automatically if they don't exist - * - Dry-run mode shows what would be applied without writing to disk - * - Errors for individual files don't stop processing of other files - * - Returns detailed summary including file paths and change types - * - * @example - * ```typescript - * // Apply all pending changes - * const result = await tool.execute({}); - * // Returns: "Applied 2 file(s) to disk:\n - src/utils.ts (create)\n - src/helper.ts (modify)" - * - * // Apply specific files - * const result2 = await tool.execute({ file_paths: ['src/utils.ts'] }); - * - * // Dry run - * const result3 = await tool.execute({ dry_run: true }); - * // Returns: "[DRY RUN] Would apply 2 file(s):\n - src/utils.ts (create)\n - src/helper.ts (modify)" - * ``` - */ - execute(input: Record): Promise; -} diff --git a/build/cli/src/agent/tools/builtin_tools/execute_command_tool.d.ts b/build/cli/src/agent/tools/builtin_tools/execute_command_tool.d.ts deleted file mode 100644 index 96d431a1..00000000 --- a/build/cli/src/agent/tools/builtin_tools/execute_command_tool.d.ts +++ /dev/null @@ -1,167 +0,0 @@ -/** - * Execute Command Tool - Executes shell commands and returns their output. - * - * This tool allows agents to execute shell commands to verify code, run tests, compile, - * lint, or perform other operations. Commands are automatically executed in the working - * directory to ensure they run in the correct location. - * - * @internal - * This tool is used by agents to verify changes, run tests, and perform other verification - * tasks. It includes automatic working directory handling, output filtering capabilities, - * and failure detection based on output patterns. - * - * @remarks - * - Commands are automatically prefixed with 'cd working_directory &&' (if autoCd is enabled) - * - Supports output filtering (head, tail, grep) for efficiency - * - Detects failure patterns in output (error, failed, exit code, etc.) - * - Captures both stdout and stderr - * - Returns formatted output with command, working directory, exit code, and output - * - * @example - * ```typescript - * const tool = new ExecuteCommandTool({ - * getWorkingDirectory: () => '/project', - * onCommandExecuted: (cmd, success, output) => { console.log('Executed:', cmd); } - * }); - * - * // Execute a command - * await tool.execute({ command: 'npm test' }); - * - * // With output filtering - * await tool.execute({ - * command: 'npm test', - * extract_lines: { head: 50, grep: 'error' } - * }); - * ``` - */ -import { BaseTool } from '../base_tool'; -/** - * Options for configuring the ExecuteCommandTool. - * - * @internal - * These callbacks and options configure command execution behavior and provide hooks - * for monitoring command execution. - * - * @property getWorkingDirectory - Optional callback to get working directory (default: process.cwd()). - * @property onCommandExecuted - Optional callback invoked after command execution with results. - * @property autoCd - If true, automatically prepend cd command (default: true). - */ -export interface ExecuteCommandToolOptions { - /** - * Optional callback to get working directory. - * - * @internal - * This callback returns the working directory where commands should be executed. - * If not provided, defaults to process.cwd(). - * - * @returns Working directory path - */ - getWorkingDirectory?: () => string; - /** - * Optional callback invoked after command execution. - * - * @internal - * This callback is invoked after each command execution with the command, success status, - * and output. Useful for logging or monitoring command execution. - * - * @param command - The executed command - * @param success - Whether command succeeded (based on exit code and output patterns) - * @param output - Command output (stdout/stderr) - */ - onCommandExecuted?: (command: string, success: boolean, output: string) => void; - /** - * If true, automatically prepend cd command (default: true). - * - * @internal - * When enabled, commands are automatically prefixed with 'cd working_directory &&' to - * ensure they run in the correct directory. This is useful when working directory differs - * from process.cwd(). - */ - autoCd?: boolean; -} -/** - * ExecuteCommandTool - Tool for executing shell commands and returning their output. - * - * This tool provides a safe way to execute shell commands with automatic working directory - * handling, output filtering, and failure detection. - * - * @internal - * The tool handles command execution, output capture, filtering, and failure detection. - * It automatically manages working directory changes and provides formatted output for easy - * consumption by agents. - */ -export declare class ExecuteCommandTool extends BaseTool { - private options; - /** - * Creates a new ExecuteCommandTool instance. - * - * @internal - * The options parameter provides callbacks and configuration for command execution. - * - * @param options - Configuration object with callbacks and options for command execution - */ - constructor(options: ExecuteCommandToolOptions); - /** - * Returns the tool name used by the agent system. - * - * @internal - * This name is used when the agent calls the tool via tool calls. - * - * @returns Tool identifier: 'execute_command' - */ - getName(): string; - getDescription(): string; - getInputSchema(): { - type: 'object'; - properties: Record; - required: string[]; - additionalProperties?: boolean; - }; - /** - * Executes the tool with the provided input. - * - * This method executes a shell command, captures its output, applies optional filters, - * and detects failure patterns. It handles both successful and failed command execution. - * - * @internal - * The method performs the following steps: - * 1. Validates command input - * 2. Automatically prepends 'cd working_directory &&' if autoCd is enabled - * 3. Executes command with proper working directory and buffer settings - * 4. Applies output filters (grep, head, tail) if specified - * 5. Detects failure patterns in output - * 6. Formats and returns result with command details and output - * - * @param input - Tool input containing command, optional working_directory, and extract_lines - * @returns Formatted string with command details, exit code, and output - * - * @throws Error if command is missing or not a string - * - * @remarks - * - Commands are automatically executed in working directory (via autoCd or cwd option) - * - Output filtering (grep, head, tail) can be combined for efficient result processing - * - Failure detection uses pattern matching on output (error, failed, exit code, etc.) - * - Both stdout and stderr are captured - * - execSync throws on non-zero exit codes, so successful execution means exit code 0 - * - Failed commands return formatted error output with exit code and status - * - * @example - * ```typescript - * // Execute a simple command - * const result = await tool.execute({ command: 'npm test' }); - * - * // With output filtering - * const result2 = await tool.execute({ - * command: 'npm test', - * extract_lines: { head: 50, grep: 'error' } - * }); - * - * // With custom working directory - * const result3 = await tool.execute({ - * command: 'ls', - * working_directory: '/tmp' - * }); - * ``` - */ - execute(input: Record): Promise; -} diff --git a/build/cli/src/agent/tools/builtin_tools/index.d.ts b/build/cli/src/agent/tools/builtin_tools/index.d.ts deleted file mode 100644 index efa0dc86..00000000 --- a/build/cli/src/agent/tools/builtin_tools/index.d.ts +++ /dev/null @@ -1,12 +0,0 @@ -/** - * Export built-in tools - */ -export * from './read_file_tool'; -export * from './search_files_tool'; -export * from './propose_change_tool'; -export * from './apply_changes_tool'; -export * from './execute_command_tool'; -export * from './manage_todos_tool'; -export * from './report_errors_tool'; -export * from './report_progress_tool'; -export * from './report_intent_tool'; diff --git a/build/cli/src/agent/tools/builtin_tools/manage_todos_tool.d.ts b/build/cli/src/agent/tools/builtin_tools/manage_todos_tool.d.ts deleted file mode 100644 index d4507317..00000000 --- a/build/cli/src/agent/tools/builtin_tools/manage_todos_tool.d.ts +++ /dev/null @@ -1,255 +0,0 @@ -/** - * Manage TODOs Tool - Tool for managing TODO list items for task tracking and progress monitoring. - * - * This tool provides a structured interface for agents to manage task lists during their reasoning - * process. It allows agents to create, update, and list TODO items with different statuses - * (pending, in_progress, completed, cancelled) to track high-level tasks that may require - * multiple steps to complete. - * - * @internal - * This tool is used by reasoning agents (IntentClassifier, ErrorDetector, ProgressDetector) - * to track tasks and maintain state across multiple agent turns. It provides a structured - * way to manage task lists that persist throughout the agent's reasoning process. - * - * The tool supports three main actions: - * - CREATE: Add new TODO items (only with pending or in_progress status) - * - UPDATE: Modify existing TODO items (change status, add notes) - * - LIST: Retrieve all TODO items with their current status - * - * The tool validates all inputs and ensures type safety using TodoStatus and TodoAction enums. - * It handles three distinct actions and provides clear error messages when validation fails. - * - * @remarks - * - The tool is designed to be flexible - it accepts multiple field names for content - * (content, description, text, task) to accommodate different agent response formats - * - CREATE action only allows PENDING or IN_PROGRESS status during creation - * - UPDATE action allows all TodoStatus values including COMPLETED and CANCELLED - * - LIST action returns formatted list with emojis and status indicators - * - * @example - * ```typescript - * const tool = new ManageTodosTool({ - * createTodo: (content, status) => { return { id: 'todo_1', content, status }; }, - * updateTodo: (id, updates) => { return true; }, - * getAllTodos: () => { return []; }, - * getActiveTodos: () => { return []; } - * }); - * - * // Create a TODO - * await tool.execute({ - * action: 'create', - * content: 'Fix bug in authentication', - * status: 'pending' - * }); - * - * // Update a TODO - * await tool.execute({ - * action: 'update', - * todo_id: 'todo_1', - * status: 'in_progress', - * notes: 'Working on it' - * }); - * - * // List all TODOs - * await tool.execute({ action: 'list' }); - * ``` - */ -import { BaseTool } from '../base_tool'; -import { TodoStatus } from '../../../data/model/think_response'; -/** - * Options for configuring the ManageTodosTool. - * - * @internal - * These callbacks are provided by the agent initializer and connect the tool - * to the underlying TODO manager (ThinkTodoManager). The tool acts as a bridge - * between the agent's tool calls and the actual TODO management logic. - * - * @property createTodo - Callback to create a new TODO item. Returns the created TODO with id, content, and status. - * @property updateTodo - Callback to update an existing TODO item. Returns true if update succeeded, false if TODO not found. - * @property getAllTodos - Callback to retrieve all TODO items regardless of status. - * @property getActiveTodos - Callback to retrieve only active TODO items (pending or in_progress status). - */ -export interface ManageTodosToolOptions { - /** - * Creates a new TODO item. - * - * @internal - * When creating a TODO, only PENDING or IN_PROGRESS statuses are allowed. - * COMPLETED and CANCELLED statuses cannot be set during creation as they represent - * terminal states that should only be reached through updates. - * - * @param content - Description of the task to be done - * @param status - Optional status (defaults to PENDING). Must be PENDING or IN_PROGRESS. - * @returns Created TODO item with generated id, content, and status - */ - createTodo: (content: string, status?: TodoStatus) => { - id: string; - content: string; - status: string; - }; - /** - * Updates an existing TODO item. - * - * @internal - * Updates can change the status to any valid TodoStatus value, including COMPLETED - * and CANCELLED. Notes can be added or updated. Related files and changes can be - * linked to track which files or changes are associated with this TODO. - * - * @param id - Unique identifier of the TODO to update - * @param updates - Object containing optional status, notes, related_files, and related_changes - * @returns true if TODO was found and updated, false if TODO not found - */ - updateTodo: (id: string, updates: { - status?: TodoStatus; - notes?: string; - related_files?: string[]; - related_changes?: string[]; - }) => boolean; - /** - * Retrieves all TODO items. - * - * @internal - * Returns all TODOs regardless of status. Used for listing and overview purposes. - * - * @returns Array of all TODO items with id, content, status, and optional notes - */ - getAllTodos: () => Array<{ - id: string; - content: string; - status: string; - notes?: string; - }>; - /** - * Retrieves only active TODO items. - * - * @internal - * Active TODOs are those with PENDING or IN_PROGRESS status. COMPLETED and CANCELLED - * items are excluded. Used to show only actionable items. - * - * @returns Array of active TODO items (pending or in_progress) - */ - getActiveTodos: () => Array<{ - id: string; - content: string; - status: string; - }>; -} -/** - * ManageTodosTool - Tool for managing TODO list items. - * - * This tool provides a structured interface for agents to manage task lists during - * their reasoning process. It supports creating new tasks, updating existing ones, - * and listing all tasks with their current status. - * - * @internal - * The tool validates all inputs and ensures type safety using TodoStatus and TodoAction - * enums. It handles three distinct actions (CREATE, UPDATE, LIST) and provides clear - * error messages when validation fails. - * - * The tool is designed to be flexible - it accepts multiple field names for content - * (content, description, text, task) to accommodate different agent response formats. - */ -export declare class ManageTodosTool extends BaseTool { - private options; - /** - * Creates a new ManageTodosTool instance. - * - * @internal - * The options parameter provides callbacks that connect this tool to the underlying - * TODO manager. This separation allows the tool to be used with different TODO - * management implementations. - * - * @param options - Configuration object with callbacks for TODO operations - */ - constructor(options: ManageTodosToolOptions); - /** - * Returns the tool name used by the agent system. - * - * @internal - * This name is used when the agent calls the tool via tool calls. - * - * @returns Tool identifier: 'manage_todos' - */ - getName(): string; - /** - * Returns the tool description shown to the agent. - * - * @internal - * This description helps the agent understand when and how to use this tool. - * It's included in the agent's available tools list. - * - * @returns Human-readable description of the tool's purpose - */ - getDescription(): string; - /** - * Returns the JSON schema for tool input validation. - * - * @internal - * The schema defines the structure and validation rules for the tool's input parameters. - * It uses enums (TodoAction, TodoStatus) to ensure type safety and prevent invalid values. - * The schema is used by the agent system to validate tool calls before execution. - * - * @returns JSON schema object defining input structure and validation rules - * - * @remarks - * - action is required and must be one of: CREATE, UPDATE, LIST - * - content is required for CREATE action - * - todo_id is required for UPDATE action - * - status uses TodoStatus enum values (pending, in_progress, completed, cancelled) - * - notes is optional and only used for UPDATE action - * - additionalProperties: true allows flexibility for future extensions - */ - getInputSchema(): { - type: 'object'; - properties: Record; - required: string[]; - additionalProperties?: boolean; - }; - /** - * Executes the tool with the provided input. - * - * This method handles three distinct actions: - * 1. CREATE: Creates a new TODO item with content and optional status - * 2. UPDATE: Updates an existing TODO item (status, notes) - * 3. LIST: Returns a formatted list of all TODO items - * - * @internal - * The method validates all inputs before processing. It uses TodoAction and TodoStatus - * enums to ensure type safety. For CREATE action, it accepts multiple field names - * (content, description, text, task) for flexibility with different agent response formats. - * - * @param input - Tool input containing action and action-specific parameters - * @returns String response indicating success or error, or formatted TODO list - * - * @throws Error if action is invalid, required fields are missing, or status values are invalid - * - * @remarks - * - CREATE action: Only PENDING or IN_PROGRESS status allowed during creation - * - UPDATE action: All TodoStatus values allowed, including COMPLETED and CANCELLED - * - LIST action: Returns formatted list with emojis and status indicators - * - All actions log their execution for debugging and monitoring - * - * @example - * // Create a TODO - * const result = await tool.execute({ - * action: 'create', - * content: 'Fix bug in authentication', - * status: 'pending' - * }); - * // Returns: "TODO created: [todo_1] Fix bug in authentication (pending)" - * - * // Update a TODO - * const result2 = await tool.execute({ - * action: 'update', - * todo_id: 'todo_1', - * status: 'in_progress', - * notes: 'Working on it' - * }); - * // Returns: "TODO updated: [todo_1]" - * - * // List all TODOs - * const result3 = await tool.execute({ action: 'list' }); - * // Returns formatted list with all TODOs - */ - execute(input: Record): Promise; -} diff --git a/build/cli/src/agent/tools/builtin_tools/propose_change_tool.d.ts b/build/cli/src/agent/tools/builtin_tools/propose_change_tool.d.ts deleted file mode 100644 index eedd399f..00000000 --- a/build/cli/src/agent/tools/builtin_tools/propose_change_tool.d.ts +++ /dev/null @@ -1,184 +0,0 @@ -/** - * Propose Change Tool - Proposes changes to files in the virtual codebase. - * - * This tool allows agents to propose modifications to files in the virtual codebase (in-memory - * representation). Changes can be created, modified, deleted, or refactored. The tool supports - * automatic application to disk when the user prompt is detected as an order (not a question). - * - * @internal - * This tool is used by agents to make code changes during their reasoning process. Changes are - * first applied to the virtual codebase (in-memory), and can optionally be automatically written - * to disk based on intent classification or explicit auto_apply parameter. - * - * The tool implements intelligent auto-apply detection: - * - If user prompt is an ORDER (create, write, make, build, set up, modify): auto_apply is enabled - * - If user prompt is a QUESTION (what, how, why, should, could): auto_apply is disabled - * - Explicit auto_apply parameter can override the auto-detection - * - * @remarks - * - Changes are always applied to virtual codebase first (in-memory) - * - Auto-apply to disk happens when shouldApplyChanges is true (from intent classifier or prompt analysis) - * - For clear orders: files are written to disk immediately - * - For questions/doubts: changes stay in memory for discussion - * - The tool validates all inputs and ensures type safety using ChangeType enum - * - * @example - * ```typescript - * const tool = new ProposeChangeTool({ - * applyChange: (change) => { return true; }, - * autoApplyToDisk: async (filePath) => { return true; }, - * getUserPrompt: () => 'Create a new file', - * getShouldApplyChanges: () => true - * }); - * - * // Propose a change (auto-apply will be determined automatically) - * await tool.execute({ - * file_path: 'src/utils/helper.ts', - * change_type: 'create', - * description: 'Create helper utility', - * suggested_code: 'export function helper() {}', - * reasoning: 'User requested to create this file' - * }); - * ``` - */ -import { BaseTool } from '../base_tool'; -import { ChangeType } from '../../../data/model/think_response'; -/** - * Options for configuring the ProposeChangeTool. - * - * @internal - * These callbacks connect the tool to the underlying change management system and provide - * hooks for auto-applying changes to disk when appropriate. - * - * @property applyChange - Callback to apply change to virtual codebase. Returns true if successful. - * @property onChangeApplied - Optional callback invoked when change is applied to virtual codebase. - * @property autoApplyToDisk - Optional callback to automatically write changes to disk when auto_apply is enabled. - * @property getUserPrompt - Optional callback to get original user prompt for intent detection (fallback). - * @property getShouldApplyChanges - Optional callback to get pre-classified intent from intent classifier. - */ -export interface ProposeChangeToolOptions { - applyChange: (change: { - file_path: string; - change_type: ChangeType; - description: string; - suggested_code: string; - reasoning: string; - }) => boolean; - onChangeApplied?: (change: any) => void; - autoApplyToDisk?: (filePath: string, operation?: ChangeType) => Promise; - getUserPrompt?: () => string | undefined; - getShouldApplyChanges?: () => boolean | undefined; -} -/** - * ProposeChangeTool - Tool for proposing changes to files in the virtual codebase. - * - * This tool provides a structured interface for agents to propose file modifications. Changes - * are applied to the virtual codebase (in-memory) and can optionally be automatically written - * to disk based on intent classification or explicit configuration. - * - * @internal - * The tool validates all inputs and ensures type safety using ChangeType enum. It implements - * intelligent auto-apply detection based on user prompt analysis or pre-classified intent. - */ -export declare class ProposeChangeTool extends BaseTool { - private options; - /** - * Creates a new ProposeChangeTool instance. - * - * @internal - * The options parameter provides callbacks that connect this tool to the underlying change - * management system and enable auto-apply functionality. - * - * @param options - Configuration object with callbacks for change operations - */ - constructor(options: ProposeChangeToolOptions); - /** - * Returns the tool name used by the agent system. - * - * @internal - * This name is used when the agent calls the tool via tool calls. - * - * @returns Tool identifier: 'propose_change' - */ - getName(): string; - getDescription(): string; - getInputSchema(): { - type: 'object'; - properties: Record; - required: string[]; - additionalProperties?: boolean; - }; - /** - * Detects if user prompt is an order (not a question). - * - * This method analyzes the user prompt to determine if it represents a clear instruction - * to perform an action (order) versus a question seeking information. - * - * @internal - * This is a fallback method used when intent classifier is not available. It uses pattern - * matching to identify order indicators (create, write, make, build, etc.) and question - * indicators (what, how, why, ?, etc.). Question indicators take priority - if a prompt - * contains both, it's treated as a question. - * - * @param prompt - Optional user prompt to analyze - * @returns true if prompt is detected as an order, false if it's a question or unclear - * - * @remarks - * - Strong question indicators (?, what, how, why, etc.) take priority over order indicators - * - Order indicators include: create, write, make, build, set up, modify, add, implement, etc. - * - If prompt contains question mark or starts with question words, it's treated as a question - * - Default behavior: if no question mark and has action verbs, treat as order - */ - private isOrderPrompt; - /** - * Executes the tool with the provided input. - * - * This method handles the complete change proposal workflow: - * 1. Validates all input parameters (file_path, change_type, description, suggested_code, reasoning) - * 2. Applies change to virtual codebase (in-memory) - * 3. Determines if auto-apply to disk should be enabled (explicit parameter, intent classifier, or prompt analysis) - * 4. Optionally writes changes to disk if auto-apply is enabled - * - * @internal - * The method validates all inputs before processing. It uses ChangeType enum to ensure - * type safety. Auto-apply detection follows a priority order: - * 1. Explicit auto_apply parameter (if provided) - * 2. Pre-classified intent from intent classifier (if available) - * 3. Fallback to user prompt analysis (if classifier not used) - * - * @param input - Tool input containing file_path, change_type, description, suggested_code, reasoning, and optional auto_apply - * @returns String response indicating success or error, including whether changes were auto-applied to disk - * - * @throws Error if required fields are missing, change_type is invalid, or file operations fail - * - * @remarks - * - All changes are applied to virtual codebase first (in-memory) - * - Auto-apply to disk only happens if shouldAutoApply is true and autoApplyToDisk callback is provided - * - For DELETE operations, special handling is required when writing to disk - * - If auto-apply fails, the change remains in virtual codebase and user can use apply_changes tool manually - * - * @example - * ```typescript - * // Propose a change (auto-apply determined automatically) - * const result = await tool.execute({ - * file_path: 'src/utils/helper.ts', - * change_type: 'create', - * description: 'Create helper utility', - * suggested_code: 'export function helper() {}', - * reasoning: 'User requested to create this file' - * }); - * // Returns: "Change proposed and automatically applied to disk: src/utils/helper.ts: Create helper utility" - * - * // Propose a change with explicit auto_apply - * const result2 = await tool.execute({ - * file_path: 'src/utils/helper.ts', - * change_type: 'modify', - * description: 'Update helper function', - * suggested_code: 'export function helper() { return true; }', - * reasoning: 'Add return value', - * auto_apply: true - * }); - * ``` - */ - execute(input: Record): Promise; -} diff --git a/build/cli/src/agent/tools/builtin_tools/read_file_tool.d.ts b/build/cli/src/agent/tools/builtin_tools/read_file_tool.d.ts deleted file mode 100644 index d885fd5f..00000000 --- a/build/cli/src/agent/tools/builtin_tools/read_file_tool.d.ts +++ /dev/null @@ -1,141 +0,0 @@ -/** - * Read File Tool - Reads file contents from repository or virtual codebase. - * - * This tool allows agents to read and examine file contents from either the virtual codebase - * (in-memory changes) or the original repository files. It provides a unified interface for - * accessing file content regardless of whether the file has been modified in the virtual codebase. - * - * @internal - * This tool is used by agents to examine code, configuration files, or any file in the codebase - * during their reasoning process. It checks the virtual codebase first (for modified files) and - * falls back to repository files if not found. - * - * @remarks - * - Virtual codebase is checked first (for files modified via propose_change) - * - Falls back to repository files if not found in virtual codebase - * - Returns formatted response with file path, line count, and code block - * - Returns error message if file is not found in either location - * - * @example - * ```typescript - * const tool = new ReadFileTool({ - * getFileContent: (filePath) => { return 'file content'; }, - * repositoryFiles: new Map([['src/utils.ts', 'export function util() {}']]) - * }); - * - * const result = await tool.execute({ file_path: 'src/utils.ts' }); - * // Returns: "File: src/utils.ts\nLines: 1\n\n```\nfile content\n```" - * ``` - */ -import { BaseTool } from '../base_tool'; -/** - * Options for configuring the ReadFileTool. - * - * @internal - * These callbacks connect the tool to the virtual codebase and repository file storage. - * - * @property getFileContent - Callback to get file content from virtual codebase. Returns content or undefined. - * @property repositoryFiles - Optional Map of repository file paths to their contents (original files). - */ -export interface ReadFileToolOptions { - /** - * Gets file content from virtual codebase. - * - * @internal - * This callback is used to retrieve file content from the in-memory virtual codebase, - * which contains files that have been modified via propose_change but not yet written to disk. - * - * @param filePath - Path to the file to read - * @returns File content as string, or undefined if file not found in virtual codebase - */ - getFileContent: (filePath: string) => string | undefined; - /** - * Optional Map of repository file paths to their contents. - * - * @internal - * This Map contains the original repository files. It's used as a fallback when - * a file is not found in the virtual codebase. - */ - repositoryFiles?: Map; -} -/** - * ReadFileTool - Tool for reading file contents from repository or virtual codebase. - * - * This tool provides a unified interface for accessing file content from either the virtual - * codebase (modified files) or the original repository files. - * - * @internal - * The tool checks the virtual codebase first, then falls back to repository files. This ensures - * that agents always see the most recent changes (from propose_change) when reading files. - */ -export declare class ReadFileTool extends BaseTool { - private options; - /** - * Creates a new ReadFileTool instance. - * - * @internal - * The options parameter provides callbacks that connect this tool to the virtual codebase - * and repository file storage. - * - * @param options - Configuration object with callbacks for file operations - */ - constructor(options: ReadFileToolOptions); - /** - * Returns the tool name used by the agent system. - * - * @internal - * This name is used when the agent calls the tool via tool calls. - * - * @returns Tool identifier: 'read_file' - */ - getName(): string; - /** - * Returns the tool description shown to the agent. - * - * @internal - * This description helps the agent understand when and how to use this tool. - * It's included in the agent's available tools list. - * - * @returns Human-readable description of the tool's purpose - */ - getDescription(): string; - getInputSchema(): { - type: 'object'; - properties: Record; - required: string[]; - additionalProperties?: boolean; - }; - /** - * Executes the tool with the provided input. - * - * This method reads file content from either the virtual codebase or repository files. - * It checks the virtual codebase first (for modified files) and falls back to repository - * files if not found. - * - * @internal - * The method validates the file_path input and then attempts to retrieve the file content - * from two sources in order: - * 1. Virtual codebase (via getFileContent callback) - contains files modified via propose_change - * 2. Repository files (via repositoryFiles Map) - contains original files - * - * @param input - Tool input containing file_path - * @returns Formatted string with file path, line count, and code block, or error message if file not found - * - * @throws Error if file_path is missing or not a string - * - * @remarks - * - Virtual codebase is checked first to ensure agents see the most recent changes - * - Response format includes file path, line count, and code block for easy reading - * - Returns error message (not exception) if file is not found in either location - * - * @example - * ```typescript - * const result = await tool.execute({ file_path: 'src/utils.ts' }); - * // Returns: "File: src/utils.ts\nLines: 10\n\n```\nexport function util() {}\n```" - * - * const result2 = await tool.execute({ file_path: 'nonexistent.ts' }); - * // Returns: "Error: File "nonexistent.ts" not found in the repository." - * ``` - */ - execute(input: Record): Promise; -} diff --git a/build/cli/src/agent/tools/builtin_tools/report_errors_tool.d.ts b/build/cli/src/agent/tools/builtin_tools/report_errors_tool.d.ts deleted file mode 100644 index 12ccd904..00000000 --- a/build/cli/src/agent/tools/builtin_tools/report_errors_tool.d.ts +++ /dev/null @@ -1,152 +0,0 @@ -/** - * Report Errors Tool - Tool for reporting detected errors in structured format. - * - * This tool allows agents to report detected errors, bugs, vulnerabilities, or issues in a - * structured format. Each error includes file path, line number (if applicable), type, severity, - * description, and optional suggestion for fixing it. - * - * @internal - * This tool is used by the ErrorDetector agent to report all errors found during code analysis. - * The tool validates and cleans error data to ensure consistency, removing markdown formatting - * and normalizing values according to IssueType and SeverityLevel enums. - * - * @remarks - * - Errors must be provided as an array of plain JSON objects - * - File paths and types are cleaned to remove markdown formatting - * - IssueType values are validated and normalized (fallback to CODE_ISSUE if invalid) - * - SeverityLevel values must be one of: critical, high, medium, low - * - Descriptions and suggestions can contain newlines but no markdown formatting - * - Line numbers are optional and parsed from strings if needed - * - * @example - * ```typescript - * const tool = new ReportErrorsTool({ - * onErrorsReported: (errors) => { console.log('Errors reported:', errors); } - * }); - * - * await tool.execute({ - * errors: [ - * { - * file: 'src/utils.ts', - * line: 42, - * type: 'bug', - * severity: 'high', - * description: 'Null pointer exception possible', - * suggestion: 'Add null check before accessing property' - * } - * ] - * }); - * ``` - */ -import { BaseTool } from '../base_tool'; -import { DetectedError } from '../../reasoning/error_detector/types'; -/** - * Options for configuring the ReportErrorsTool. - * - * @internal - * The callback connects the tool to the error reporting system, allowing errors to be - * processed and stored after validation and cleaning. - * - * @property onErrorsReported - Callback invoked with cleaned and validated errors array. - */ -export interface ReportErrorsToolOptions { - /** - * Callback invoked when errors are reported. - * - * @internal - * This callback receives the cleaned and validated errors array. Errors have been - * normalized, markdown removed, and validated against IssueType and SeverityLevel enums. - * - * @param errors - Array of cleaned and validated DetectedError objects - */ - onErrorsReported: (errors: DetectedError[]) => void; -} -/** - * ReportErrorsTool - Tool for reporting detected errors in structured format. - * - * This tool provides a structured interface for agents to report errors found during code - * analysis. It validates, cleans, and normalizes error data before passing it to the callback. - * - * @internal - * The tool performs extensive cleaning and validation: - * - Removes markdown formatting from file paths, types, descriptions, and suggestions - * - Validates IssueType values (with fallback to CODE_ISSUE if invalid) - * - Validates SeverityLevel values (must be one of: critical, high, medium, low) - * - Parses line numbers from strings if needed - * - Extracts first error from concatenated error descriptions - */ -export declare class ReportErrorsTool extends BaseTool { - private options; - /** - * Creates a new ReportErrorsTool instance. - * - * @internal - * The options parameter provides the callback that receives cleaned and validated errors. - * - * @param options - Configuration object with callback for error reporting - */ - constructor(options: ReportErrorsToolOptions); - /** - * Returns the tool name used by the agent system. - * - * @internal - * This name is used when the agent calls the tool via tool calls. - * - * @returns Tool identifier: 'report_errors' - */ - getName(): string; - getDescription(): string; - getInputSchema(): { - type: 'object'; - properties: Record; - required: string[]; - additionalProperties?: boolean; - }; - /** - * Executes the tool with the provided input. - * - * This method processes an array of errors, validates and cleans each error, and then - * passes the cleaned errors to the callback. The cleaning process removes markdown - * formatting, normalizes values, and validates against IssueType and SeverityLevel enums. - * - * @internal - * The method performs extensive validation and cleaning: - * 1. Validates errors is an array - * 2. For each error: validates required fields, cleans file paths and types, normalizes - * IssueType and SeverityLevel, parses line numbers, cleans descriptions and suggestions - * 3. Passes cleaned errors to callback - * - * @param input - Tool input containing errors array - * @returns String response indicating success or error details - * - * @throws Error if errors is not an array, required fields are missing, or validation fails - * - * @remarks - * - Empty errors array is valid and returns success message - * - File paths are cleaned to remove markdown, prefixes, and newlines - * - IssueType values are validated and normalized (fallback to CODE_ISSUE if invalid) - * - SeverityLevel values must be exactly one of: critical, high, medium, low - * - Line numbers are parsed from strings if needed (extracts first number found) - * - Descriptions and suggestions are cleaned but preserve newlines for readability - * - If multiple errors are concatenated in description, only first is extracted - * - * @example - * ```typescript - * const result = await tool.execute({ - * errors: [ - * { - * file: '**src/utils.ts**', - * line: '42', - * type: 'BUG', - * severity: 'HIGH', - * description: '**Null pointer** exception', - * suggestion: 'Add null check' - * } - * ] - * }); - * // Errors are cleaned: file='src/utils.ts', line=42, type='bug', severity='high' - * // Returns: "Successfully reported 1 error(s). Errors have been recorded for analysis." - * ``` - */ - execute(input: Record): Promise; -} diff --git a/build/cli/src/agent/tools/builtin_tools/report_intent_tool.d.ts b/build/cli/src/agent/tools/builtin_tools/report_intent_tool.d.ts deleted file mode 100644 index e36281bc..00000000 --- a/build/cli/src/agent/tools/builtin_tools/report_intent_tool.d.ts +++ /dev/null @@ -1,137 +0,0 @@ -/** - * Report Intent Tool - Tool for reporting intent classification decision in structured format. - * - * This tool allows agents to report their intent classification decision, indicating whether - * the user prompt is an ORDER (should apply changes) or a QUESTION (should not apply changes). - * This is the primary way for agents to report their classification after analyzing the prompt. - * - * @internal - * This tool is used by the IntentClassifier agent to report classification decisions. The tool - * validates and cleans the reasoning text, ensuring it's plain text without markdown formatting, - * and validates the confidence level against the ConfidenceLevel enum. - * - * @remarks - * - shouldApplyChanges must be a boolean (true for orders, false for questions) - * - reasoning is cleaned to remove markdown formatting but preserves newlines - * - confidence must be one of: high, medium, low (from ConfidenceLevel enum) - * - This is the PRIMARY way to report intent classification - agents MUST use this tool - * - * @example - * ```typescript - * const tool = new ReportIntentTool({ - * onIntentReported: (shouldApply, reasoning, confidence) => { - * console.log('Intent:', shouldApply, confidence); - * } - * }); - * - * await tool.execute({ - * shouldApplyChanges: true, - * reasoning: 'User said "create a file" which is a clear order', - * confidence: 'high' - * }); - * ``` - */ -import { BaseTool } from '../base_tool'; -import { ConfidenceLevel } from '../../reasoning/intent_classifier/types'; -/** - * Options for configuring the ReportIntentTool. - * - * @internal - * The callback connects the tool to the intent reporting system, allowing classification - * decisions to be processed and stored. - * - * @property onIntentReported - Callback invoked with classification decision, reasoning, and confidence. - */ -export interface ReportIntentToolOptions { - /** - * Callback invoked when intent is reported. - * - * @internal - * This callback receives the classification decision (shouldApplyChanges), cleaned reasoning, - * and validated confidence level. The reasoning has been cleaned to remove markdown formatting. - * - * @param shouldApplyChanges - true if prompt is an order, false if it's a question - * @param reasoning - Cleaned reasoning text explaining the classification - * @param confidence - Confidence level (high, medium, or low) - */ - onIntentReported: (shouldApplyChanges: boolean, reasoning: string, confidence: ConfidenceLevel) => void; -} -/** - * ReportIntentTool - Tool for reporting intent classification decisions. - * - * This tool provides a structured interface for agents to report their intent classification - * decisions. It validates inputs, cleans reasoning text, and ensures confidence levels are valid. - * - * @internal - * The tool performs validation and cleaning: - * - Validates shouldApplyChanges is a boolean - * - Cleans reasoning to remove markdown formatting (preserves newlines) - * - Validates confidence level against ConfidenceLevel enum - * - Passes cleaned data to callback - */ -export declare class ReportIntentTool extends BaseTool { - private options; - /** - * Creates a new ReportIntentTool instance. - * - * @internal - * The options parameter provides the callback that receives the classification decision. - * - * @param options - Configuration object with callback for intent reporting - */ - constructor(options: ReportIntentToolOptions); - /** - * Returns the tool name used by the agent system. - * - * @internal - * This name is used when the agent calls the tool via tool calls. - * - * @returns Tool identifier: 'report_intent' - */ - getName(): string; - getDescription(): string; - getInputSchema(): { - type: 'object'; - properties: Record; - required: string[]; - additionalProperties?: boolean; - }; - /** - * Executes the tool with the provided input. - * - * This method validates and processes the intent classification decision, cleans the reasoning - * text, and passes the cleaned data to the callback. - * - * @internal - * The method performs the following steps: - * 1. Validates shouldApplyChanges is provided and converts to boolean - * 2. Validates reasoning is provided and is a string - * 3. Cleans reasoning to remove markdown formatting (preserves newlines) - * 4. Validates confidence is provided and is a valid ConfidenceLevel enum value - * 5. Passes cleaned data to callback - * - * @param input - Tool input containing shouldApplyChanges, reasoning, and confidence - * @returns String response indicating success - * - * @throws Error if required fields are missing, reasoning is empty after cleaning, or confidence is invalid - * - * @remarks - * - shouldApplyChanges is converted to boolean (handles truthy/falsy values) - * - Reasoning is cleaned to remove markdown but preserves newlines for readability - * - Confidence is normalized to lowercase and validated against ConfidenceLevel enum - * - Empty reasoning after cleaning throws an error - * - * @example - * ```typescript - * const result = await tool.execute({ - * shouldApplyChanges: true, - * reasoning: '**User said** "create a file" which is a clear order', - * confidence: 'HIGH' - * }); - * // Reasoning is cleaned: 'User said "create a file" which is a clear order' - * // Confidence is normalized: 'high' - * // Returns: "Successfully reported intent classification: shouldApplyChanges=true, confidence=high. Classification has been recorded." - * ``` - */ - execute(input: Record): Promise; -} diff --git a/build/cli/src/agent/tools/builtin_tools/report_progress_tool.d.ts b/build/cli/src/agent/tools/builtin_tools/report_progress_tool.d.ts deleted file mode 100644 index dfebf78c..00000000 --- a/build/cli/src/agent/tools/builtin_tools/report_progress_tool.d.ts +++ /dev/null @@ -1,144 +0,0 @@ -/** - * Report Progress Tool - Tool for reporting task progress in structured format. - * - * This tool allows agents to report the progress percentage of a task based on code changes - * analysis. It reports the completion percentage (0-100) and a brief summary of the assessment. - * This is the primary way for agents to report progress after analyzing changes. - * - * @internal - * This tool is used by the ProgressDetector agent to report task completion percentage. The tool - * validates progress is within 0-100 range, cleans the summary text to remove markdown formatting, - * and rounds progress to integer for consistency. - * - * @remarks - * - progress must be a number between 0 and 100 (inclusive) - * - Progress can be provided as number or string (extracts number from string) - * - Progress is rounded to integer for consistency - * - summary is cleaned to remove markdown formatting but preserves newlines - * - This is the PRIMARY way to report progress - agents MUST use this tool - * - * @example - * ```typescript - * const tool = new ReportProgressTool({ - * onProgressReported: (progress, summary) => { - * console.log(`Progress: ${progress}%`); - * } - * }); - * - * await tool.execute({ - * progress: 75, - * summary: 'Most changes are complete, only tests remaining' - * }); - * ``` - */ -import { BaseTool } from '../base_tool'; -/** - * Options for configuring the ReportProgressTool. - * - * @internal - * The callback connects the tool to the progress reporting system, allowing progress - * assessments to be processed and stored. - * - * @property onProgressReported - Callback invoked with progress percentage and cleaned summary. - */ -export interface ReportProgressToolOptions { - /** - * Callback invoked when progress is reported. - * - * @internal - * This callback receives the progress percentage (0-100, rounded to integer) and cleaned - * summary text. The summary has been cleaned to remove markdown formatting. - * - * @param progress - Progress percentage (0-100, integer) - * @param summary - Cleaned summary text explaining the progress assessment - */ - onProgressReported: (progress: number, summary: string) => void; -} -/** - * ReportProgressTool - Tool for reporting task progress in structured format. - * - * This tool provides a structured interface for agents to report task completion percentage. - * It validates progress range, cleans summary text, and ensures data consistency. - * - * @internal - * The tool performs validation and cleaning: - * - Validates progress is within 0-100 range - * - Parses progress from string if needed (extracts first number) - * - Rounds progress to integer for consistency - * - Cleans summary to remove markdown formatting (preserves newlines) - * - Passes cleaned data to callback - */ -export declare class ReportProgressTool extends BaseTool { - private options; - /** - * Creates a new ReportProgressTool instance. - * - * @internal - * The options parameter provides the callback that receives the progress assessment. - * - * @param options - Configuration object with callback for progress reporting - */ - constructor(options: ReportProgressToolOptions); - /** - * Returns the tool name used by the agent system. - * - * @internal - * This name is used when the agent calls the tool via tool calls. - * - * @returns Tool identifier: 'report_progress' - */ - getName(): string; - getDescription(): string; - getInputSchema(): { - type: 'object'; - properties: Record; - required: string[]; - additionalProperties?: boolean; - }; - /** - * Executes the tool with the provided input. - * - * This method validates and processes the progress assessment, parses progress from number - * or string, validates the range, cleans the summary text, and passes the cleaned data - * to the callback. - * - * @internal - * The method performs the following steps: - * 1. Validates progress is provided - * 2. Parses progress from number or string (extracts first number from string) - * 3. Validates progress is within 0-100 range - * 4. Rounds progress to integer for consistency - * 5. Validates summary is provided and is a string - * 6. Cleans summary to remove markdown formatting (preserves newlines) - * 7. Passes cleaned data to callback - * - * @param input - Tool input containing progress and summary - * @returns String response indicating success - * - * @throws Error if progress is missing, invalid, or out of range; or if summary is missing or empty after cleaning - * - * @remarks - * - Progress can be provided as number or string (extracts first number from string) - * - Progress is rounded to integer for consistency (e.g., 75.5 becomes 76) - * - Summary is cleaned to remove markdown but preserves newlines for readability - * - Empty summary after cleaning throws an error - * - * @example - * ```typescript - * // With number - * const result = await tool.execute({ - * progress: 75, - * summary: '**Most changes** are complete' - * }); - * // Progress: 75, Summary: 'Most changes are complete' - * - * // With string - * const result2 = await tool.execute({ - * progress: '50%', - * summary: 'Halfway done' - * }); - * // Progress: 50, Summary: 'Halfway done' - * ``` - */ - execute(input: Record): Promise; -} diff --git a/build/cli/src/agent/tools/builtin_tools/search_files_tool.d.ts b/build/cli/src/agent/tools/builtin_tools/search_files_tool.d.ts deleted file mode 100644 index b926b64b..00000000 --- a/build/cli/src/agent/tools/builtin_tools/search_files_tool.d.ts +++ /dev/null @@ -1,157 +0,0 @@ -/** - * Search Files Tool - Searches for files by name or content. - * - * This tool allows agents to search for files in the repository by name, path, or content - * keywords. It returns a list of matching file paths, with optional result limiting for - * efficiency. - * - * @internal - * This tool is used by agents to find files during their reasoning process. It delegates - * the actual search logic to the searchFiles callback, which can implement various search - * strategies (name matching, path patterns, content search, etc.). - * - * @remarks - * - query is required and can be a file name, path pattern, or content keyword - * - max_results defaults to 1000 but can be set higher (>= 10000 returns all results) - * - Results are formatted as a numbered list for easy reading - * - Returns empty message if no files match the query - * - * @example - * ```typescript - * const tool = new SearchFilesTool({ - * searchFiles: (query) => { - * // Implement search logic - * return ['src/utils.ts', 'src/helper.ts']; - * } - * }); - * - * // Search with default limit - * await tool.execute({ query: 'utils' }); - * - * // Search with custom limit - * await tool.execute({ query: 'test', max_results: 5000 }); - * ``` - */ -import { BaseTool } from '../base_tool'; -/** - * Options for configuring the SearchFilesTool. - * - * @internal - * These callbacks connect the tool to the file search system, allowing various search - * strategies to be implemented. - * - * @property searchFiles - Callback to perform file search. Returns array of matching file paths. - * @property getAllFiles - Optional callback to get all files (for comprehensive searches). - */ -export interface SearchFilesToolOptions { - /** - * Performs file search based on query. - * - * @internal - * This callback implements the actual search logic. It can search by file name, path - * pattern, content keywords, or any combination. The implementation is flexible and - * can use various search strategies. - * - * @param query - Search query (file name, path pattern, or content keyword) - * @returns Array of matching file paths - */ - searchFiles: (query: string) => string[]; - /** - * Optional callback to get all files. - * - * @internal - * This callback can be used for comprehensive searches when max_results is very high - * (>= 10000). It returns all files in the repository. - * - * @returns Array of all file paths - */ - getAllFiles?: () => string[]; -} -/** - * SearchFilesTool - Tool for searching files by name or content. - * - * This tool provides a unified interface for file searching, with result limiting and - * formatting capabilities. - * - * @internal - * The tool validates the query, delegates search to the callback, limits results if needed, - * and formats the response as a numbered list. For very large max_results (>= 10000), it - * returns all results without limiting. - */ -export declare class SearchFilesTool extends BaseTool { - private options; - /** - * Creates a new SearchFilesTool instance. - * - * @internal - * The options parameter provides callbacks that implement the search logic. - * - * @param options - Configuration object with callbacks for file search - */ - constructor(options: SearchFilesToolOptions); - /** - * Returns the tool name used by the agent system. - * - * @internal - * This name is used when the agent calls the tool via tool calls. - * - * @returns Tool identifier: 'search_files' - */ - getName(): string; - /** - * Returns the tool description shown to the agent. - * - * @internal - * This description helps the agent understand when and how to use this tool. - * It's included in the agent's available tools list. - * - * @returns Human-readable description of the tool's purpose - */ - getDescription(): string; - getInputSchema(): { - type: 'object'; - properties: Record; - required: string[]; - additionalProperties?: boolean; - }; - /** - * Executes the tool with the provided input. - * - * This method performs a file search based on the query, limits results if needed, and - * formats the response as a numbered list. - * - * @internal - * The method performs the following steps: - * 1. Validates query is provided and is a string - * 2. Validates max_results is at least 1 - * 3. Delegates search to searchFiles callback - * 4. Limits results if max_results is reasonable (< 10000) - * 5. Formats results as numbered list or returns empty message - * - * @param input - Tool input containing query and optional max_results - * @returns Formatted string with numbered list of matching files, or empty message if none found - * - * @throws Error if query is missing or not a string, or if max_results is less than 1 - * - * @remarks - * - max_results defaults to 1000 for comprehensive searches - * - For max_results >= 10000, all results are returned (no limiting) - * - Results are formatted as a numbered list for easy reading - * - Returns empty message (not exception) if no files match - * - * @example - * ```typescript - * // Search with default limit - * const result = await tool.execute({ query: 'utils' }); - * // Returns: "Found 2 file(s) matching "utils":\n\n1. src/utils.ts\n2. src/utils/helper.ts" - * - * // Search with custom limit - * const result2 = await tool.execute({ query: 'test', max_results: 5000 }); - * - * // No results - * const result3 = await tool.execute({ query: 'nonexistent' }); - * // Returns: "No files found matching query: "nonexistent"" - * ``` - */ - execute(input: Record): Promise; -} diff --git a/build/cli/src/agent/tools/index.d.ts b/build/cli/src/agent/tools/index.d.ts deleted file mode 100644 index edc66997..00000000 --- a/build/cli/src/agent/tools/index.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -/** - * Export all tool-related classes - */ -export * from './base_tool'; -export * from './tool_registry'; -export * from './tool_executor'; diff --git a/build/cli/src/agent/tools/tool_executor.d.ts b/build/cli/src/agent/tools/tool_executor.d.ts deleted file mode 100644 index 8bf3da83..00000000 --- a/build/cli/src/agent/tools/tool_executor.d.ts +++ /dev/null @@ -1,34 +0,0 @@ -/** - * Tool Executor for Agent SDK - * Executes tool calls and returns results - */ -import { ToolRegistry } from './tool_registry'; -import { ToolCall, ToolResult } from '../types'; -export declare class ToolExecutor { - private registry; - constructor(registry: ToolRegistry); - /** - * Execute a single tool call - */ - execute(toolCall: ToolCall): Promise; - /** - * Execute multiple tool calls in parallel - */ - executeAll(toolCalls: ToolCall[]): Promise; - /** - * Execute multiple tool calls sequentially - */ - executeAllSequential(toolCalls: ToolCall[]): Promise; - /** - * Check if tool is available - */ - isToolAvailable(name: string): boolean; - /** - * Get available tool names - */ - getAvailableTools(): string[]; - /** - * Get all tool definitions - */ - getToolDefinitions(): import("../types").ToolDefinition[]; -} diff --git a/build/cli/src/agent/tools/tool_registry.d.ts b/build/cli/src/agent/tools/tool_registry.d.ts deleted file mode 100644 index 2baff479..00000000 --- a/build/cli/src/agent/tools/tool_registry.d.ts +++ /dev/null @@ -1,40 +0,0 @@ -/** - * Tool Registry for managing available tools - */ -import { BaseTool } from './base_tool'; -import { ToolDefinition } from '../types'; -export declare class ToolRegistry { - private tools; - /** - * Register a tool - */ - register(tool: BaseTool): void; - /** - * Register multiple tools - */ - registerAll(tools: BaseTool[]): void; - /** - * Get tool by name - */ - get(name: string): BaseTool | undefined; - /** - * Check if tool exists - */ - has(name: string): boolean; - /** - * Get all tool definitions - */ - getAllDefinitions(): ToolDefinition[]; - /** - * Get all registered tool names - */ - getToolNames(): string[]; - /** - * Clear all tools - */ - clear(): void; - /** - * Get tool count - */ - getCount(): number; -} diff --git a/build/cli/src/agent/types/agent_types.d.ts b/build/cli/src/agent/types/agent_types.d.ts deleted file mode 100644 index 00614670..00000000 --- a/build/cli/src/agent/types/agent_types.d.ts +++ /dev/null @@ -1,99 +0,0 @@ -/** - * Agent types for the Agent SDK - */ -import { Message } from './message_types'; -import { ToolCall, ToolResult } from './tool_types'; -export type ToolPermissionStrategy = 'allowlist' | 'blocklist' | 'all'; -export type StreamChunk = { - type: 'text' | 'tool_call' | 'reasoning' | 'done'; - content: string; - toolCall?: ToolCall; -}; -export interface ToolPermissions { - strategy: ToolPermissionStrategy; - allowed?: string[]; - blocked?: string[]; -} -export interface BudgetConfig { - maxCost?: number; - maxTokens?: number; - warnAtPercent?: number; -} -export interface TimeoutConfig { - apiCall?: number; - toolExecution?: number; - totalSession?: number; -} -export interface RetryConfig { - maxRetries?: number; - initialDelay?: number; - maxDelay?: number; - backoffMultiplier?: number; - retryableErrors?: number[]; -} -export interface AgentOptions { - model: string; - /** OpenCode server URL (e.g. http://localhost:4096) */ - serverUrl: string; - systemPrompt?: string; - maxTurns?: number; - maxTokens?: number; - temperature?: number; - tools?: any[]; - onTurnComplete?: (turn: TurnResult) => void; - onError?: (error: Error) => void; - onToolCall?: (toolCall: ToolCall) => void; - onToolResult?: (result: ToolResult) => void; - streaming?: boolean; - onStreamChunk?: (chunk: StreamChunk) => void; - toolPermissions?: ToolPermissions; - maxContextLength?: number; - contextCompressionEnabled?: boolean; - sessionId?: string; - persistSession?: boolean; - trackMetrics?: boolean; - onMetrics?: (metrics: Metrics) => void; - budget?: BudgetConfig; - timeouts?: TimeoutConfig; - retry?: RetryConfig; -} -export interface TurnResult { - turnNumber: number; - assistantMessage: string; - toolCalls: ToolCall[]; - toolResults?: ToolResult[]; - reasoning?: string; - timestamp: number; -} -export interface Metrics { - totalTokens: { - input: number; - output: number; - }; - totalCost?: number; - apiCalls: number; - toolCalls: number; - averageLatency: number; - totalDuration: number; - errors: number; -} -export interface AgentResult { - finalResponse: string; - turns: TurnResult[]; - toolCalls: ToolCall[]; - messages: Message[]; - totalTokens?: { - input: number; - output: number; - }; - metrics?: Metrics; - error?: Error; - truncated?: boolean; - budgetExceeded?: boolean; - timeoutExceeded?: boolean; -} -export interface ParsedResponse { - text: string; - toolCalls?: ToolCall[]; - reasoning?: string; -} diff --git a/build/cli/src/agent/types/index.d.ts b/build/cli/src/agent/types/index.d.ts deleted file mode 100644 index dc2183fb..00000000 --- a/build/cli/src/agent/types/index.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -/** - * Export all types - */ -export * from './message_types'; -export * from './tool_types'; -export * from './agent_types'; diff --git a/build/cli/src/agent/types/message_types.d.ts b/build/cli/src/agent/types/message_types.d.ts deleted file mode 100644 index b563a623..00000000 --- a/build/cli/src/agent/types/message_types.d.ts +++ /dev/null @@ -1,38 +0,0 @@ -/** - * Message types for the Agent SDK - * Compatible with Anthropic Messages API format - */ -export type MessageRole = 'system' | 'user' | 'assistant'; -export interface TextContent { - type: 'text'; - text: string; -} -export interface ToolUseContent { - type: 'tool_use'; - id: string; - name: string; - input: Record; -} -export interface ToolResultContent { - type: 'tool_result'; - tool_use_id: string; - content: string | any; - is_error?: boolean; -} -export type ContentBlock = TextContent | ToolUseContent | ToolResultContent; -export interface Message { - role: MessageRole; - content: string | ContentBlock[]; -} -export interface SystemMessage extends Message { - role: 'system'; - content: string; -} -export interface UserMessage extends Message { - role: 'user'; - content: string | ContentBlock[]; -} -export interface AssistantMessage extends Message { - role: 'assistant'; - content: ContentBlock[]; -} diff --git a/build/cli/src/agent/types/response_schema.d.ts b/build/cli/src/agent/types/response_schema.d.ts deleted file mode 100644 index df1396be..00000000 --- a/build/cli/src/agent/types/response_schema.d.ts +++ /dev/null @@ -1,39 +0,0 @@ -/** - * JSON Schema for Agent responses - * Used with OpenCode JSON mode - */ -export declare const AGENT_RESPONSE_SCHEMA: { - type: string; - properties: { - response: { - type: string; - description: string; - }; - tool_calls: { - type: string; - description: string; - items: { - type: string; - properties: { - id: { - type: string; - description: string; - }; - name: { - type: string; - description: string; - }; - input: { - type: string; - description: string; - additionalProperties: boolean; - }; - }; - required: string[]; - additionalProperties: boolean; - }; - }; - }; - required: string[]; - additionalProperties: boolean; -}; diff --git a/build/cli/src/agent/types/tool_types.d.ts b/build/cli/src/agent/types/tool_types.d.ts deleted file mode 100644 index 08267463..00000000 --- a/build/cli/src/agent/types/tool_types.d.ts +++ /dev/null @@ -1,29 +0,0 @@ -/** - * Tool types for the Agent SDK - */ -export interface ToolDefinition { - name: string; - description: string; - inputSchema: { - type: 'object'; - properties: Record; - required: string[]; - additionalProperties?: boolean; - }; -} -export interface ToolCall { - id: string; - name: string; - input: Record; -} -export interface ToolResult { - toolCallId: string; - content: string | any; - isError?: boolean; - errorMessage?: string; -} -export interface ToolExecutionResult { - success: boolean; - result: any; - error?: string; -} diff --git a/build/cli/src/agent/utils/error_handler.d.ts b/build/cli/src/agent/utils/error_handler.d.ts deleted file mode 100644 index 3807bc06..00000000 --- a/build/cli/src/agent/utils/error_handler.d.ts +++ /dev/null @@ -1,32 +0,0 @@ -/** - * Error handler for Agent SDK - */ -export declare class AgentError extends Error { - code: string; - context?: any | undefined; - constructor(message: string, code: string, context?: any | undefined); -} -export declare class ToolExecutionError extends AgentError { - toolName: string; - toolInput?: any | undefined; - constructor(message: string, toolName: string, toolInput?: any | undefined); -} -export declare class APIError extends AgentError { - statusCode?: number | undefined; - response?: any | undefined; - constructor(message: string, statusCode?: number | undefined, response?: any | undefined); -} -export declare class ValidationError extends AgentError { - field?: string | undefined; - constructor(message: string, field?: string | undefined); -} -export declare class ErrorHandler { - /** - * Handle and format errors - */ - static handle(error: unknown): Error; - /** - * Check if error is retryable - */ - static isRetryable(error: Error): boolean; -} diff --git a/build/cli/src/agent/utils/index.d.ts b/build/cli/src/agent/utils/index.d.ts deleted file mode 100644 index ef432e8d..00000000 --- a/build/cli/src/agent/utils/index.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -/** - * Export all utilities - */ -export * from './response_parser'; -export * from './prompt_builder'; -export * from './error_handler'; diff --git a/build/cli/src/agent/utils/prompt_builder.d.ts b/build/cli/src/agent/utils/prompt_builder.d.ts deleted file mode 100644 index c7ec643a..00000000 --- a/build/cli/src/agent/utils/prompt_builder.d.ts +++ /dev/null @@ -1,25 +0,0 @@ -/** - * Prompt builder for Agent SDK - * Builds prompts that include tool definitions and conversation history - */ -import { Message } from '../types'; -import { ToolDefinition } from '../types'; -export declare class PromptBuilder { - /** - * Build a complete prompt from messages and tools - * This converts the message history into a format suitable for OpenCode - */ - static buildPrompt(messages: Message[], tools?: ToolDefinition[]): string; - /** - * Build tools section for prompt (simplified to save tokens) - */ - private static buildToolsSection; - /** - * Format a message for the prompt - */ - private static formatMessage; - /** - * Get response schema for JSON mode - */ - private static getResponseSchema; -} diff --git a/build/cli/src/agent/utils/response_parser.d.ts b/build/cli/src/agent/utils/response_parser.d.ts deleted file mode 100644 index 280b54c4..00000000 --- a/build/cli/src/agent/utils/response_parser.d.ts +++ /dev/null @@ -1,30 +0,0 @@ -/** - * Response parser for OpenCode JSON responses - */ -import { ParsedResponse } from '../types'; -export declare class ResponseParser { - /** - * Parse JSON response from OpenCode - * Expected format: - * { - * "reasoning": "...", - * "response": "...", - * "tool_calls": [ - * { - * "id": "call_1", - * "name": "read_file", - * "input": { "file_path": "..." } - * } - * ] - * } - */ - static parse(jsonResponse: any): ParsedResponse; - /** - * Generate a unique tool call ID - */ - private static generateToolCallId; - /** - * Validate parsed response - */ - static validate(parsed: ParsedResponse): boolean; -} diff --git a/build/cli/src/agent_tester.d.ts b/build/cli/src/agent_tester.d.ts deleted file mode 100644 index b7988016..00000000 --- a/build/cli/src/agent_tester.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -#!/usr/bin/env node -export {}; diff --git a/build/cli/src/agent_tester_commands.d.ts b/build/cli/src/agent_tester_commands.d.ts deleted file mode 100644 index d15dc675..00000000 --- a/build/cli/src/agent_tester_commands.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -/** - * Agent SDK Test Commands - * All testing commands for the Agent SDK - */ -import { Command } from 'commander'; -/** - * Register all agent test commands to the provided program - */ -export declare function registerAgentTestCommands(program: Command): void; diff --git a/build/cli/src/data/graph/add_project_item_response.d.ts b/build/cli/src/data/graph/add_project_item_response.d.ts deleted file mode 100644 index 7eb188fb..00000000 --- a/build/cli/src/data/graph/add_project_item_response.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -export interface AddProjectItemResponse { - addProjectV2ItemById: { - item: { - id: string; - }; - }; -} diff --git a/build/cli/src/data/graph/ai_responses.d.ts b/build/cli/src/data/graph/ai_responses.d.ts deleted file mode 100644 index 5c1e9a7b..00000000 --- a/build/cli/src/data/graph/ai_responses.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -export interface PatchSummary { - filePath: string; - summary: string; - changes: string[]; -} diff --git a/build/cli/src/data/model/ai_response.d.ts b/build/cli/src/data/model/ai_response.d.ts deleted file mode 100644 index 0135b4d4..00000000 --- a/build/cli/src/data/model/ai_response.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -export interface AiResponse { - text_response: string; - action: 'none' | 'analyze_files'; - related_files: string[]; - complete: boolean; -} diff --git a/build/cli/src/data/model/ai_response_schema.d.ts b/build/cli/src/data/model/ai_response_schema.d.ts deleted file mode 100644 index 54adfc1c..00000000 --- a/build/cli/src/data/model/ai_response_schema.d.ts +++ /dev/null @@ -1,31 +0,0 @@ -/** - * JSON Schema for AiResponse interface - * This schema is used to enforce structured JSON responses from the AI - */ -export declare const AI_RESPONSE_JSON_SCHEMA: { - type: string; - properties: { - text_response: { - type: string; - description: string; - }; - action: { - type: string; - enum: string[]; - description: string; - }; - related_files: { - type: string; - items: { - type: string; - }; - description: string; - }; - complete: { - type: string; - description: string; - }; - }; - required: string[]; - additionalProperties: boolean; -}; diff --git a/build/cli/src/data/model/codebase_analysis_schema.d.ts b/build/cli/src/data/model/codebase_analysis_schema.d.ts deleted file mode 100644 index b2bb7f82..00000000 --- a/build/cli/src/data/model/codebase_analysis_schema.d.ts +++ /dev/null @@ -1,30 +0,0 @@ -/** - * JSON Schema for codebase analysis responses - * Used in Step 0 of the thinking process to analyze codebase structure - */ -export declare const CODEBASE_ANALYSIS_JSON_SCHEMA: { - type: string; - description: string; - items: { - type: string; - properties: { - path: { - type: string; - description: string; - }; - description: { - type: string; - description: string; - }; - relationships: { - type: string; - description: string; - items: { - type: string; - }; - }; - }; - required: string[]; - additionalProperties: boolean; - }; -}; diff --git a/build/cli/src/data/model/supabase_config.d.ts b/build/cli/src/data/model/supabase_config.d.ts deleted file mode 100644 index 3ac8c9fe..00000000 --- a/build/cli/src/data/model/supabase_config.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -export declare class SupabaseConfig { - private url; - private key; - constructor(url: string, key: string); - getUrl(): string; - getKey(): string; -} diff --git a/build/cli/src/data/model/think_response.d.ts b/build/cli/src/data/model/think_response.d.ts deleted file mode 100644 index 1a5e0941..00000000 --- a/build/cli/src/data/model/think_response.d.ts +++ /dev/null @@ -1,82 +0,0 @@ -/** - * Status levels for TODO items - */ -export declare enum TodoStatus { - PENDING = "pending", - IN_PROGRESS = "in_progress", - COMPLETED = "completed", - CANCELLED = "cancelled" -} -/** - * Actions for managing TODOs - */ -export declare enum TodoAction { - CREATE = "create", - UPDATE = "update", - LIST = "list" -} -/** - * Types of changes that can be proposed to files - */ -export declare enum ChangeType { - CREATE = "create", - MODIFY = "modify", - DELETE = "delete", - REFACTOR = "refactor" -} -export interface FileAnalysis { - path: string; - key_findings: string; - relevance: 'high' | 'medium' | 'low'; -} -export interface ProposedChange { - file_path: string; - change_type: ChangeType; - description: string; - suggested_code?: string; - reasoning: string; -} -export interface ThinkResponse { - reasoning: string; - action: 'search_files' | 'read_file' | 'analyze_code' | 'propose_changes' | 'complete' | 'update_todos'; - files_to_search?: string[]; - files_to_read?: string[]; - analyzed_files?: FileAnalysis[]; - proposed_changes?: ProposedChange[]; - todo_updates?: { - create?: Array<{ - content: string; - status?: TodoStatus; - }>; - update?: Array<{ - id: string; - status?: TodoStatus; - notes?: string; - }>; - }; - complete: boolean; - final_analysis?: string; -} -export interface ThinkStep { - step_number: number; - action: string; - reasoning: string; - files_involved?: string[]; - findings?: string; - timestamp: number; -} -export interface ThinkTodoItem { - id: string; - content: string; - status: TodoStatus; - created_at: number; - updated_at: number; - completed_at?: number; - related_files?: string[]; - related_changes?: string[]; - notes?: string; -} -export interface ThinkTodoList { - items: ThinkTodoItem[]; - last_updated: number; -} diff --git a/build/cli/src/data/model/think_response_schema.d.ts b/build/cli/src/data/model/think_response_schema.d.ts deleted file mode 100644 index c86c7e38..00000000 --- a/build/cli/src/data/model/think_response_schema.d.ts +++ /dev/null @@ -1,137 +0,0 @@ -/** - * JSON Schema for ThinkResponse interface - * This schema is used for structured AI reasoning and analysis responses - */ -export declare const THINK_RESPONSE_JSON_SCHEMA: { - type: string; - properties: { - reasoning: { - type: string; - description: string; - }; - action: { - type: string; - enum: string[]; - description: string; - }; - files_to_search: { - type: string; - items: { - type: string; - }; - description: string; - }; - files_to_read: { - type: string; - items: { - type: string; - }; - description: string; - }; - analyzed_files: { - type: string; - items: { - type: string; - properties: { - path: { - type: string; - }; - key_findings: { - type: string; - }; - relevance: { - type: string; - enum: string[]; - }; - }; - required: string[]; - additionalProperties: boolean; - }; - description: string; - }; - proposed_changes: { - type: string; - items: { - type: string; - properties: { - file_path: { - type: string; - }; - change_type: { - type: string; - enum: string[]; - }; - description: { - type: string; - }; - suggested_code: { - type: string; - }; - reasoning: { - type: string; - }; - }; - required: string[]; - additionalProperties: boolean; - }; - description: string; - }; - complete: { - type: string; - description: string; - }; - final_analysis: { - type: string; - description: string; - }; - todo_updates: { - type: string; - description: string; - properties: { - create: { - type: string; - items: { - type: string; - properties: { - content: { - type: string; - }; - status: { - type: string; - enum: string[]; - }; - }; - required: string[]; - additionalProperties: boolean; - }; - description: string; - }; - update: { - type: string; - items: { - type: string; - properties: { - id: { - type: string; - }; - status: { - type: string; - enum: string[]; - }; - notes: { - type: string; - }; - }; - required: string[]; - additionalProperties: boolean; - }; - description: string; - }; - }; - required: string[]; - additionalProperties: boolean; - }; - }; - required: string[]; - additionalProperties: boolean; -}; diff --git a/build/cli/src/data/repository/supabase_repository.d.ts b/build/cli/src/data/repository/supabase_repository.d.ts deleted file mode 100644 index f1a9ecc2..00000000 --- a/build/cli/src/data/repository/supabase_repository.d.ts +++ /dev/null @@ -1,98 +0,0 @@ -import { SupabaseConfig } from '../model/supabase_config'; -export interface AICachedFileInfo { - owner: string; - repository: string; - branch: string; - file_name: string; - path: string; - sha: string; - description: string; - consumes: string[]; - consumed_by: string[]; - error_counter_total?: number; - error_counter_critical?: number; - error_counter_high?: number; - error_counter_medium?: number; - error_counter_low?: number; - error_types?: string[]; - errors_payload?: string; - created_at?: string; - last_updated?: string; -} -export declare class SupabaseRepository { - private readonly AI_FILE_CACHE_TABLE; - private readonly MAX_BATCH_SIZE; - private readonly DEFAULT_TIMEOUT; - private supabase; - constructor(config: SupabaseConfig); - /** - * Set or update AI file cache entry - * If SHA hasn't changed, this will update the entry - */ - setAIFileCache: (owner: string, repository: string, branch: string, fileInfo: { - file_name: string; - path: string; - sha: string; - description: string; - consumes: string[]; - consumed_by: string[]; - error_counter_total?: number; - error_counter_critical?: number; - error_counter_high?: number; - error_counter_medium?: number; - error_counter_low?: number; - error_types?: string[]; - errors_payload?: string; - }) => Promise; - /** - * Get AI file cache entry by path - */ - getAIFileCache: (owner: string, repository: string, branch: string, filePath: string) => Promise; - /** - * Get all AI file cache entries for a branch - */ - getAIFileCachesByBranch: (owner: string, repository: string, branch: string) => Promise; - /** - * Remove AI file cache entry by path - */ - removeAIFileCacheByPath: (owner: string, repository: string, branch: string, filePath: string) => Promise; - /** - * Duplicate AI file cache entries from one branch to another - */ - duplicateAIFileCacheByBranch: (owner: string, repository: string, sourceBranch: string, targetBranch: string) => Promise; - /** - * Remove all AI file cache entries for a branch - */ - removeAIFileCacheByBranch: (owner: string, repository: string, branch: string) => Promise; - /** - * Get SHA by path (for checking if file is cached) - */ - getShasumByPath: (owner: string, repository: string, branch: string, path: string) => Promise; - /** - * Get distinct paths for a branch - */ - getDistinctPaths: (owner: string, repository: string, branch: string) => Promise; - /** - * Get distinct branches for an owner/repository - */ - getDistinctBranches: (owner: string, repository: string) => Promise; - /** - * Get AI file cache entry by SHA (searches across all branches for the same owner/repository) - * Returns the first match found, which can be used to reuse descriptions - */ - getAIFileCacheBySha: (owner: string, repository: string, sha: string) => Promise; - /** - * Verify that a table exists in Supabase - */ - verifyTableExists: (tableName: string) => Promise<{ - exists: boolean; - error?: string; - }>; - /** - * Verify that an RPC function exists in Supabase - */ - verifyRpcFunctionExists: (functionName: string, testParams: any) => Promise<{ - exists: boolean; - error?: string; - }>; -} diff --git a/build/cli/src/mcp_tester_commands.d.ts b/build/cli/src/mcp_tester_commands.d.ts deleted file mode 100644 index 07c2ea4b..00000000 --- a/build/cli/src/mcp_tester_commands.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -/** - * MCP Tester Commands - * CLI commands for testing MCP functionality - */ -import { Command } from 'commander'; -export declare function registerMCPTestCommands(program: Command): void; diff --git a/build/cli/src/sub_agent_tester_commands.d.ts b/build/cli/src/sub_agent_tester_commands.d.ts deleted file mode 100644 index b61c8cd4..00000000 --- a/build/cli/src/sub_agent_tester_commands.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -/** - * SubAgent Tester Commands - * CLI commands for testing SubAgent functionality - */ -import { Command } from 'commander'; -export declare function registerSubAgentTestCommands(program: Command): void; diff --git a/build/cli/src/tec_tester_commands.d.ts b/build/cli/src/tec_tester_commands.d.ts deleted file mode 100644 index a223fa69..00000000 --- a/build/cli/src/tec_tester_commands.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -/** - * TEC (TypeScript Error Checker) Tester Commands - * CLI commands for testing error detection system - */ -import { Command } from 'commander'; -export declare function registerTECTestCommands(program: Command): void; diff --git a/build/cli/src/data/model/__tests__/ai_response_schema.test.d.ts b/build/cli/src/usecase/actions/__tests__/create_release_use_case.test.d.ts similarity index 100% rename from build/cli/src/data/model/__tests__/ai_response_schema.test.d.ts rename to build/cli/src/usecase/actions/__tests__/create_release_use_case.test.d.ts diff --git a/build/cli/src/data/model/__tests__/think_response_schema.test.d.ts b/build/cli/src/usecase/actions/__tests__/create_tag_use_case.test.d.ts similarity index 100% rename from build/cli/src/data/model/__tests__/think_response_schema.test.d.ts rename to build/cli/src/usecase/actions/__tests__/create_tag_use_case.test.d.ts diff --git a/build/cli/src/utils/__tests__/reasoning_visualizer.test.d.ts b/build/cli/src/usecase/actions/__tests__/initial_setup_use_case.test.d.ts similarity index 100% rename from build/cli/src/utils/__tests__/reasoning_visualizer.test.d.ts rename to build/cli/src/usecase/actions/__tests__/initial_setup_use_case.test.d.ts diff --git a/build/github_action/src/data/model/__tests__/think_response_schema.test.d.ts b/build/cli/src/usecase/actions/__tests__/publish_github_action_use_case.test.d.ts similarity index 100% rename from build/github_action/src/data/model/__tests__/think_response_schema.test.d.ts rename to build/cli/src/usecase/actions/__tests__/publish_github_action_use_case.test.d.ts diff --git a/build/github_action/src/utils/__tests__/reasoning_visualizer.test.d.ts b/build/cli/src/usecase/actions/__tests__/recommend_steps_use_case.test.d.ts similarity index 100% rename from build/github_action/src/utils/__tests__/reasoning_visualizer.test.d.ts rename to build/cli/src/usecase/actions/__tests__/recommend_steps_use_case.test.d.ts diff --git a/build/cli/src/usecase/actions/__tests__/vector_action_use_case.test.d.ts b/build/cli/src/usecase/actions/__tests__/vector_action_use_case.test.d.ts deleted file mode 100644 index 69d0ee60..00000000 --- a/build/cli/src/usecase/actions/__tests__/vector_action_use_case.test.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Tests for VectorActionUseCase - Orphaned Branch Detection - */ -export {}; diff --git a/build/cli/src/usecase/actions/detect_errors_use_case.d.ts b/build/cli/src/usecase/actions/detect_errors_use_case.d.ts deleted file mode 100644 index aa3d8582..00000000 --- a/build/cli/src/usecase/actions/detect_errors_use_case.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Execution } from '../../data/model/execution'; -import { Result } from '../../data/model/result'; -import { ParamUseCase } from '../base/param_usecase'; -export declare class DetectErrorsUseCase implements ParamUseCase { - taskId: string; - private issueRepository; - private branchRepository; - private aiRepository; - invoke(param: Execution): Promise; -} diff --git a/build/cli/src/usecase/actions/vector_action_removal_use_case.d.ts b/build/cli/src/usecase/actions/vector_action_removal_use_case.d.ts deleted file mode 100644 index 38e75fbe..00000000 --- a/build/cli/src/usecase/actions/vector_action_removal_use_case.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Execution } from '../../data/model/execution'; -import { Result } from '../../data/model/result'; -import { ParamUseCase } from '../base/param_usecase'; -export declare class VectorActionRemovalUseCase implements ParamUseCase { - taskId: string; - invoke(param: Execution): Promise; - private removeAICacheByBranch; -} diff --git a/build/cli/src/usecase/actions/vector_action_use_case.d.ts b/build/cli/src/usecase/actions/vector_action_use_case.d.ts deleted file mode 100644 index 7b80611f..00000000 --- a/build/cli/src/usecase/actions/vector_action_use_case.d.ts +++ /dev/null @@ -1,176 +0,0 @@ -import { Execution } from '../../data/model/execution'; -import { Result } from '../../data/model/result'; -import { ParamUseCase } from '../base/param_usecase'; -/** - * VectorActionUseCase - Processes repository files and creates AI cache in Supabase. - * - * This use case is responsible for: - * - Processing files from GitHub repositories and generating AI descriptions - * - Caching file metadata (descriptions, imports, error information) in Supabase - * - Detecting and removing orphaned branches from the cache - * - Reusing cached data across branches when files have the same SHA - * - * @internal - * This class is used internally by the SingleActionUseCase when the AI cache action is triggered. - * It processes files sequentially per branch and maintains a cache of file metadata for efficient - * codebase analysis and search operations. - */ -export declare class VectorActionUseCase implements ParamUseCase { - taskId: string; - private fileRepository; - private branchRepository; - private aiRepository; - private fileImportAnalyzer; - private fileCacheManager; - private codebaseAnalyzer; - constructor(); - /** - * Main entry point for the VectorActionUseCase. - * - * Processes repository files and creates/updates AI cache in Supabase. The process includes: - * 1. Validating configuration (Supabase, AI) - * 2. Determining which branches to process (specific branch or all branches) - * 3. Processing each branch: analyzing files, generating descriptions, detecting errors - * 4. Cleaning up orphaned branches (branches that no longer exist in GitHub) - * - * @internal - * This method orchestrates the entire cache building process. It handles errors gracefully - * and continues processing even if individual branches fail. - * - * @param param - Execution parameters containing repository info, tokens, AI config, and Supabase config - * @returns Array of Result objects indicating success/failure of each operation - * - * @remarks - * - If no specific branch is provided via `param.commit.branch`, all branches are processed - * - Orphaned branch detection runs after processing all branches to ensure accurate comparison - * - Each branch is processed independently; failures in one branch don't stop processing of others - * - * @example - * ```typescript - * const useCase = new VectorActionUseCase(); - * const results = await useCase.invoke(execution); - * // Results contain information about processed files, reused cache, and orphaned branches - * ``` - */ - invoke(param: Execution): Promise; - /** - * Processes and caches files for a specific branch. - * - * This method handles the complete file processing pipeline for a single branch: - * 1. Retrieves all files from the repository for the given branch - * 2. Builds relationship maps (imports/exports) for all files - * 3. For each file: - * - Calculates SHA to check if file has changed - * - Skips if SHA matches existing cache (optimization) - * - Reuses description/errors if SHA exists in another branch - * - Generates new AI description if file is new or changed - * - Detects errors using ErrorDetector - * - Saves metadata to Supabase - * 4. Removes files from cache that no longer exist in the repository - * - * @internal - * This is a private method called by invoke() for each branch. It's designed to be - * idempotent - running it multiple times on the same branch is safe and efficient. - * - * @param param - Execution parameters - * @param branch - Branch name to process - * @param branchIndex - Current branch index (for progress logging) - * @param totalBranches - Total number of branches being processed (for progress logging) - * - * @returns Object containing: - * - results: Array of Result objects for this branch - * - filesProcessed: Number of files successfully processed and saved - * - filesReused: Number of files that reused cache from other branches - * - filesSkipped: Number of files skipped (unchanged, same SHA) - * - filesGenerated: Number of files that required new AI description generation - * - filesRemoved: Number of files removed from cache (no longer in repository) - * - success: Whether the branch processing completed successfully - * - * @remarks - * - File processing is optimized: files with unchanged SHA are skipped entirely - * - SHA-based reuse allows sharing descriptions across branches for identical files - * - Error detection is optional and failures don't block file caching - * - The cleanup phase (removing deleted files) runs after processing all files - * - * @example - * ```typescript - * const result = await prepareCacheOnBranch(execution, 'develop', 1, 3); - * // result.filesProcessed = 150, result.filesReused = 50, result.filesSkipped = 200 - * ``` - */ - private prepareCacheOnBranch; - /** - * Removes orphaned branches from Supabase AI cache. - * - * An orphaned branch is a branch that exists in Supabase but no longer exists in GitHub. - * This method compares all branches in Supabase against all branches in GitHub to identify - * and remove orphaned branches. - * - * @internal - * This is an internal method used by the VectorActionUseCase. It should not be called directly. - * - * @param param - Execution parameters containing owner, repo, and Supabase config - * @param githubBranches - Array of all branch names that exist in GitHub (must be complete list, not just processed branches) - * - * @returns Array of Result objects indicating success/failure of the operation - * - * @remarks - * - Branch names are normalized (trimmed) before comparison - * - Comparison is case-sensitive (GitHub branch names are case-sensitive) - * - Invalid branch names (null, undefined, empty) are filtered out - * - If removal of a branch fails, the error is logged but processing continues - * - * @example - * ```typescript - * // This method is called internally by invoke() after processing branches - * // It receives ALL branches from GitHub, not just the ones being processed - * const allBranches = await branchRepository.getListOfBranches(owner, repo, token); - * const results = await removeOrphanedBranches(execution, allBranches); - * ``` - */ - private removeOrphanedBranches; - /** - * Detects errors, bugs, and code quality issues in a single file using ErrorDetector. - * - * This method uses the ErrorDetector agent to analyze a file for: - * - Syntax errors and bugs - * - Security vulnerabilities - * - Code quality issues - * - Best practice violations - * - * The analysis is limited to the target file only (analyzeOnlyTargetFile: true) to: - * - Reduce processing time - * - Lower API costs - * - Prevent analysis loops - * - Keep error detection focused and fast - * - * @internal - * This is a private method called during file processing. Error detection is optional - * and failures don't block file caching. The method is designed to be lightweight - * and focused on single-file analysis. - * - * @param param - Execution parameters containing AI config and repository info - * @param branch - Branch name where the file exists - * @param filePath - Path to the file to analyze - * @param fileContent - Content of the file to analyze - * - * @returns Object containing error counts by severity and error details, or null if: - * - AI configuration is missing - * - Error detection fails - * - File analysis cannot be completed - * - * @remarks - * - Uses maxTurns: 10 to prevent infinite loops in error detection - * - analyzeOnlyTargetFile: true ensures only the target file is analyzed (not dependencies) - * - Errors are categorized by severity: critical, high, medium, low - * - Error types are extracted and stored for filtering/searching - * - Full error details are stored as JSON payload for detailed analysis - * - * @example - * ```typescript - * const errorInfo = await detectErrorsForFile(execution, 'develop', 'src/file.ts', content); - * // errorInfo = { error_counter_total: 5, error_counter_critical: 1, ... } - * ``` - */ - private detectErrorsForFile; -} diff --git a/build/cli/src/usecase/steps/commit/__tests__/notify_new_commit_on_issue_use_case.test.d.ts b/build/cli/src/usecase/steps/commit/__tests__/notify_new_commit_on_issue_use_case.test.d.ts new file mode 100644 index 00000000..cb0ff5c3 --- /dev/null +++ b/build/cli/src/usecase/steps/commit/__tests__/notify_new_commit_on_issue_use_case.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/cli/src/usecase/steps/common/services/codebase_analyzer.d.ts b/build/cli/src/usecase/steps/common/services/codebase_analyzer.d.ts deleted file mode 100644 index 5a63f75d..00000000 --- a/build/cli/src/usecase/steps/common/services/codebase_analyzer.d.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { Execution } from '../../../../data/model/execution'; -import { AiRepository } from '../../../../data/repository/ai_repository'; -import { FileImportAnalyzer } from './file_import_analyzer'; -import { FileCacheManager } from './file_cache_manager'; -export interface FileAnalysisResult { - path: string; - description: string; - consumes: string[]; - consumed_by: string[]; -} -/** - * Service for analyzing codebase structure and generating file descriptions - */ -export declare class CodebaseAnalyzer { - private aiRepository; - private fileImportAnalyzer; - private fileCacheManager; - constructor(aiRepository: AiRepository, fileImportAnalyzer: FileImportAnalyzer, fileCacheManager: FileCacheManager); - /** - * Generate codebase analysis with file descriptions and relationships - * This runs before the main reasoning loop to provide context - * Uses relationship map built from imports + AI descriptions in batches - */ - generateCodebaseAnalysis(param: Execution, repositoryFiles: Map, question: string): Promise; - /** - * Generate basic description from file path (fallback) - */ - generateBasicDescription(path: string): string; - /** - * Generate fallback file descriptions when AI analysis fails - */ - generateFallbackFileDescriptions(files: Array<[string, string]>): FileAnalysisResult[]; - /** - * Format codebase analysis for inclusion in AI context - */ - formatCodebaseAnalysisForContext(analysis: FileAnalysisResult[]): string; -} diff --git a/build/cli/src/usecase/steps/common/services/comment_formatter.d.ts b/build/cli/src/usecase/steps/common/services/comment_formatter.d.ts deleted file mode 100644 index c0013f16..00000000 --- a/build/cli/src/usecase/steps/common/services/comment_formatter.d.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { ThinkStep, ProposedChange, FileAnalysis } from '../../../../data/model/think_response'; -import { ThinkTodoManager } from '../think_todo_manager'; -/** - * Service for formatting GitHub comments and code changes - */ -export declare class CommentFormatter { - private readonly GITHUB_COMMENT_MAX_LENGTH; - /** - * Format the complete reasoning comment for GitHub - */ - formatReasoningComment(question: string, description: string, steps: ThinkStep[], analyzedFiles: Map, proposedChanges: ProposedChange[], finalAnalysis: string, totalIterations: number, todoManager: ThinkTodoManager): string; - /** - * Format a single proposed change - */ - formatProposedChange(change: ProposedChange, index: number): string; - /** - * Detect programming language from file path/extension - */ - detectLanguageFromPath(filePath: string): string; - /** - * Get emoji for action type - */ - getActionEmoji(action: string): string; - /** - * Format action name for display - */ - formatActionName(action: string): string; - /** - * Get emoji for change type - */ - getChangeTypeEmoji(changeType: string): string; -} diff --git a/build/cli/src/usecase/steps/common/services/file_cache_manager.d.ts b/build/cli/src/usecase/steps/common/services/file_cache_manager.d.ts deleted file mode 100644 index 3ae0e95f..00000000 --- a/build/cli/src/usecase/steps/common/services/file_cache_manager.d.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { Execution } from '../../../../data/model/execution'; -import { SupabaseRepository } from '../../../../data/repository/supabase_repository'; -import { CachedFileInfo } from './types'; -/** - * Service for managing AI file cache in Supabase - */ -export declare class FileCacheManager { - private supabaseRepository; - /** - * Normalize file path for consistent comparison - * Removes leading ./ and normalizes path separators - */ - private normalizePath; - /** - * Calculate SHA256 hash of file content - */ - calculateFileSHA(content: string): string; - /** - * Initialize Supabase repository if config is available - */ - initSupabaseRepository(param: Execution): SupabaseRepository | null; - /** - * Load cache from Supabase (or return empty map if Supabase not available) - * Uses normalized paths for consistent lookup - */ - loadAICache(param: Execution): Promise>; - /** - * Get cached file info by path (with path normalization) - */ - getCachedFile(cache: Map, filePath: string): CachedFileInfo | undefined; - /** - * Save cache entry to Supabase - * Normalizes paths before saving - */ - saveAICacheEntry(param: Execution, filePath: string, fileInfo: CachedFileInfo, consumes: string[], consumedBy: string[]): Promise; -} diff --git a/build/cli/src/usecase/steps/common/services/file_import_analyzer.d.ts b/build/cli/src/usecase/steps/common/services/file_import_analyzer.d.ts deleted file mode 100644 index f2b5da10..00000000 --- a/build/cli/src/usecase/steps/common/services/file_import_analyzer.d.ts +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Service for extracting imports and building file relationship maps - * Supports multiple programming languages - */ -export declare class FileImportAnalyzer { - /** - * Extract imports from a file regardless of programming language - */ - extractImportsFromFile(filePath: string, content: string): string[]; - /** - * Resolve relative import path to absolute path - */ - resolveRelativePath(baseDir: string, relativePath: string): string; - /** - * Build relationship map from all files by extracting imports - * Also builds reverse map (consumed_by) - */ - buildRelationshipMap(repositoryFiles: Map): { - consumes: Map; - consumedBy: Map; - }; -} diff --git a/build/cli/src/usecase/steps/common/services/file_search_service.d.ts b/build/cli/src/usecase/steps/common/services/file_search_service.d.ts deleted file mode 100644 index 14be3a66..00000000 --- a/build/cli/src/usecase/steps/common/services/file_search_service.d.ts +++ /dev/null @@ -1,13 +0,0 @@ -/** - * Service for building file indexes and searching files - */ -export declare class FileSearchService { - /** - * Build file index for quick lookup by filename or directory - */ - buildFileIndex(files: Map): Map; - /** - * Search files by search terms (filename, directory, pattern, or content) - */ - searchFiles(searchTerms: string[], fileIndex: Map, repositoryFiles?: Map): string[]; -} diff --git a/build/cli/src/usecase/steps/common/services/types.d.ts b/build/cli/src/usecase/steps/common/services/types.d.ts deleted file mode 100644 index 69de0d14..00000000 --- a/build/cli/src/usecase/steps/common/services/types.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -/** - * Shared types for codebase analysis services - */ -export interface FileRelationshipMap { - consumes: Map; - consumedBy: Map; -} diff --git a/build/cli/src/usecase/steps/common/think_code_manager.d.ts b/build/cli/src/usecase/steps/common/think_code_manager.d.ts deleted file mode 100644 index 465bde74..00000000 --- a/build/cli/src/usecase/steps/common/think_code_manager.d.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { ProposedChange } from '../../../data/model/think_response'; -/** - * Manages virtual code state - keeps files in memory and applies proposed changes - * so subsequent reasoning steps can see the accumulated progress - */ -export declare class ThinkCodeManager { - private originalFiles; - private virtualFiles; - private appliedChanges; - private allAppliedChanges; - /** - * Initialize with original repository files - */ - initialize(originalFiles: Map): void; - /** - * Get current state of a file (with applied changes) - */ - getFileContent(filePath: string): string | undefined; - /** - * Get all virtual files - */ - getAllFiles(): Map; - /** - * Check if a file has been modified - */ - isFileModified(filePath: string): boolean; - /** - * Get changes applied to a specific file - */ - getFileChanges(filePath: string): ProposedChange[]; - /** - * Apply a proposed change to the virtual codebase - */ - applyChange(change: ProposedChange): boolean; - /** - * Check if a change has already been applied (to avoid duplicates) - */ - hasChangeBeenApplied(change: ProposedChange): boolean; - /** - * Get summary of all applied changes - */ - getChangesSummary(): string; - /** - * Get context about what has changed for the AI - */ - getContextForAI(): string; - /** - * Simple similarity check for change descriptions - */ - private areSimilar; - /** - * Get statistics - */ - getStats(): { - totalFiles: number; - modifiedFiles: number; - totalChanges: number; - }; -} diff --git a/build/cli/src/usecase/steps/common/think_todo_manager.d.ts b/build/cli/src/usecase/steps/common/think_todo_manager.d.ts deleted file mode 100644 index 72b63399..00000000 --- a/build/cli/src/usecase/steps/common/think_todo_manager.d.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { ThinkTodoItem, TodoStatus } from '../../../data/model/think_response'; -import { ProposedChange } from '../../../data/model/think_response'; -/** - * Manages TODO list for the reasoning process - * Similar to how the assistant tracks high-level tasks vs iterative steps - */ -export declare class ThinkTodoManager { - private todos; - private nextId; - /** - * Initialize with optional initial todos - */ - initialize(initialTodos?: Array<{ - content: string; - status?: TodoStatus; - }>): void; - /** - * Create a new TODO item - */ - createTodo(content: string, status?: TodoStatus): ThinkTodoItem; - /** - * Update an existing TODO item - */ - updateTodo(id: string, updates: { - status?: TodoStatus; - notes?: string; - related_files?: string[]; - related_changes?: string[]; - }): boolean; - /** - * Get all TODOs - */ - getAllTodos(): ThinkTodoItem[]; - /** - * Get TODOs by status - */ - getTodosByStatus(status: ThinkTodoItem['status']): ThinkTodoItem[]; - /** - * Get active TODOs (pending or in_progress) - */ - getActiveTodos(): ThinkTodoItem[]; - /** - * Get completion statistics - */ - getStats(): { - total: number; - pending: number; - in_progress: number; - completed: number; - cancelled: number; - completion_rate: number; - }; - /** - * Get formatted TODO list for AI context - */ - getContextForAI(): string; - /** - * Link a TODO to proposed changes - */ - linkTodoToChanges(todoId: string, changes: ProposedChange[]): void; - /** - * Auto-update TODO status based on progress - * If changes are applied for a TODO, mark it as in_progress or completed - */ - autoUpdateFromChanges(changes: ProposedChange[]): void; - /** - * Get summary for final report - */ - getSummary(): string; -} diff --git a/build/cli/src/usecase/steps/common/think_use_case_2.d.ts b/build/cli/src/usecase/steps/common/think_use_case_2.d.ts deleted file mode 100644 index 0fceaf79..00000000 --- a/build/cli/src/usecase/steps/common/think_use_case_2.d.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { Execution } from '../../../data/model/execution'; -import { Result } from '../../../data/model/result'; -import { ParamUseCase } from '../../base/param_usecase'; -export declare class ThinkUseCase implements ParamUseCase { - taskId: string; - private aiRepository; - private fileRepository; - private issueRepository; - private fileImportAnalyzer; - private fileCacheManager; - private codebaseAnalyzer; - private fileSearchService; - private commentFormatter; - private readonly MAX_ITERATIONS; - private readonly MAX_FILES_TO_ANALYZE; - private readonly MAX_CONSECUTIVE_SEARCHES; - private readonly MAX_FILES_PER_READ; - constructor(); - invoke(param: Execution): Promise; - private getIssueDescription; - private performReasoningStep; - private generateFinalAnalysis; - /** - * Detect generic search terms that are too common and not useful - */ - private detectGenericSearchTerms; -} diff --git a/build/cli/src/usecase/steps/issue/__tests__/assign_members_to_issue_use_case.test.d.ts b/build/cli/src/usecase/steps/issue/__tests__/assign_members_to_issue_use_case.test.d.ts new file mode 100644 index 00000000..cb0ff5c3 --- /dev/null +++ b/build/cli/src/usecase/steps/issue/__tests__/assign_members_to_issue_use_case.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/cli/src/usecase/steps/issue/__tests__/close_issue_after_merging_use_case.test.d.ts b/build/cli/src/usecase/steps/issue/__tests__/close_issue_after_merging_use_case.test.d.ts new file mode 100644 index 00000000..cb0ff5c3 --- /dev/null +++ b/build/cli/src/usecase/steps/issue/__tests__/close_issue_after_merging_use_case.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/cli/src/usecase/steps/issue/__tests__/label_deploy_added_use_case.test.d.ts b/build/cli/src/usecase/steps/issue/__tests__/label_deploy_added_use_case.test.d.ts new file mode 100644 index 00000000..cb0ff5c3 --- /dev/null +++ b/build/cli/src/usecase/steps/issue/__tests__/label_deploy_added_use_case.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/cli/src/usecase/steps/issue/__tests__/link_issue_project_use_case.test.d.ts b/build/cli/src/usecase/steps/issue/__tests__/link_issue_project_use_case.test.d.ts new file mode 100644 index 00000000..cb0ff5c3 --- /dev/null +++ b/build/cli/src/usecase/steps/issue/__tests__/link_issue_project_use_case.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/cli/src/usecase/steps/issue/__tests__/move_issue_to_in_progress_use_case.test.d.ts b/build/cli/src/usecase/steps/issue/__tests__/move_issue_to_in_progress_use_case.test.d.ts new file mode 100644 index 00000000..cb0ff5c3 --- /dev/null +++ b/build/cli/src/usecase/steps/issue/__tests__/move_issue_to_in_progress_use_case.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/cli/src/usecase/steps/issue/__tests__/prepare_branches_use_case.test.d.ts b/build/cli/src/usecase/steps/issue/__tests__/prepare_branches_use_case.test.d.ts new file mode 100644 index 00000000..cb0ff5c3 --- /dev/null +++ b/build/cli/src/usecase/steps/issue/__tests__/prepare_branches_use_case.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/cli/src/usecase/steps/issue/__tests__/remove_issue_branches_use_case.test.d.ts b/build/cli/src/usecase/steps/issue/__tests__/remove_issue_branches_use_case.test.d.ts new file mode 100644 index 00000000..cb0ff5c3 --- /dev/null +++ b/build/cli/src/usecase/steps/issue/__tests__/remove_issue_branches_use_case.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/cli/src/usecase/steps/issue/__tests__/remove_not_needed_branches_use_case.test.d.ts b/build/cli/src/usecase/steps/issue/__tests__/remove_not_needed_branches_use_case.test.d.ts new file mode 100644 index 00000000..cb0ff5c3 --- /dev/null +++ b/build/cli/src/usecase/steps/issue/__tests__/remove_not_needed_branches_use_case.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/cli/src/usecase/steps/pull_request/__tests__/link_pull_request_issue_use_case.test.d.ts b/build/cli/src/usecase/steps/pull_request/__tests__/link_pull_request_issue_use_case.test.d.ts new file mode 100644 index 00000000..cb0ff5c3 --- /dev/null +++ b/build/cli/src/usecase/steps/pull_request/__tests__/link_pull_request_issue_use_case.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/cli/src/usecase/steps/pull_request/__tests__/link_pull_request_project_use_case.test.d.ts b/build/cli/src/usecase/steps/pull_request/__tests__/link_pull_request_project_use_case.test.d.ts new file mode 100644 index 00000000..cb0ff5c3 --- /dev/null +++ b/build/cli/src/usecase/steps/pull_request/__tests__/link_pull_request_project_use_case.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/cli/src/usecase/steps/pull_request/__tests__/update_pull_request_description_use_case.test.d.ts b/build/cli/src/usecase/steps/pull_request/__tests__/update_pull_request_description_use_case.test.d.ts new file mode 100644 index 00000000..cb0ff5c3 --- /dev/null +++ b/build/cli/src/usecase/steps/pull_request/__tests__/update_pull_request_description_use_case.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/cli/src/usecase/steps/pull_request/check_changes_pull_request_size_use_case.d.ts b/build/cli/src/usecase/steps/pull_request/check_changes_pull_request_size_use_case.d.ts deleted file mode 100644 index 139ed5e4..00000000 --- a/build/cli/src/usecase/steps/pull_request/check_changes_pull_request_size_use_case.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Execution } from "../../../data/model/execution"; -import { Result } from "../../../data/model/result"; -import { ParamUseCase } from "../../base/param_usecase"; -export declare class CheckChangesPullRequestSizeUseCase implements ParamUseCase { - taskId: string; - private branchRepository; - private issueRepository; - private projectRepository; - invoke(param: Execution): Promise; -} diff --git a/build/cli/src/utils/__tests__/setup_files.test.d.ts b/build/cli/src/utils/__tests__/setup_files.test.d.ts new file mode 100644 index 00000000..cb0ff5c3 --- /dev/null +++ b/build/cli/src/utils/__tests__/setup_files.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/cli/src/utils/constants.d.ts b/build/cli/src/utils/constants.d.ts index f9c9b80c..a83f4ea2 100644 --- a/build/cli/src/utils/constants.d.ts +++ b/build/cli/src/utils/constants.d.ts @@ -1,6 +1,5 @@ -export declare const COMMAND = "giik"; -export declare const TITLE = "Giik"; -export declare const REPO_URL = "https://github.com/landamessenger/git-board-flow"; +export declare const TITLE = "Copilot"; +export declare const REPO_URL = "https://github.com/vypdev/copilot"; /** Default OpenCode model: provider/modelID (e.g. opencode/kimi-k2.5-free). Reuse for CLI, action and Ai fallbacks. */ export declare const OPENCODE_DEFAULT_MODEL = "opencode/kimi-k2.5-free"; /** Timeout in ms for OpenCode HTTP requests (session create, message, diff). Agent calls can be slow (e.g. plan analyzing repo). */ @@ -202,8 +201,8 @@ export declare const ACTIONS: { readonly DETECT_POTENTIAL_PROBLEMS: "detect_potential_problems_action"; readonly RECOMMEND_STEPS: "recommend_steps_action"; }; -/** Hidden HTML comment prefix for bugbot findings (issue/PR comments). Format: */ -export declare const BUGBOT_MARKER_PREFIX = "gbf-bugbot"; +/** Hidden HTML comment prefix for bugbot findings (issue/PR comments). Format: */ +export declare const BUGBOT_MARKER_PREFIX = "copilot-bugbot"; /** Max number of individual bugbot comments to create per issue/PR. Excess findings get one summary comment suggesting to review locally. */ export declare const BUGBOT_MAX_COMMENTS = 20; /** Minimum severity to publish (findings below this are dropped). Order: high > medium > low > info. */ diff --git a/build/cli/src/utils/reasoning_visualizer.d.ts b/build/cli/src/utils/reasoning_visualizer.d.ts deleted file mode 100644 index 8c909e33..00000000 --- a/build/cli/src/utils/reasoning_visualizer.d.ts +++ /dev/null @@ -1,61 +0,0 @@ -export declare class ReasoningVisualizer { - private currentIteration; - private maxIterations; - private startTime; - private lastAction; - private todoStats; - private filesRead; - private filesAnalyzed; - private changesApplied; - initialize(maxIterations: number): void; - updateIteration(iteration: number): void; - updateTodoStats(stats: { - total: number; - pending: number; - in_progress: number; - completed: number; - }): void; - updateFilesRead(count: number): void; - updateFilesAnalyzed(count: number): void; - updateChangesApplied(count: number): void; - /** - * Show a clean header for the reasoning process - */ - showHeader(question: string): void; - /** - * Show current iteration status with progress bar - */ - showIterationStatus(action: string, reasoning: string): void; - /** - * Show TODO status - */ - showTodoStatus(): void; - /** - * Show file and change statistics - */ - showStats(): void; - /** - * Show action result summary - */ - showActionResult(action: string, result: { - success: boolean; - message: string; - details?: string[]; - }): void; - /** - * Show completion summary - */ - showCompletion(_finalAnalysis?: string): void; - /** - * Create a visual progress bar - */ - private createProgressBar; - /** - * Get emoji for action type - */ - private getActionEmoji; - /** - * Clear current line and show updated status - */ - updateStatus(action: string, reasoning: string): void; -} diff --git a/build/cli/src/utils/setup_files.d.ts b/build/cli/src/utils/setup_files.d.ts new file mode 100644 index 00000000..c870c050 --- /dev/null +++ b/build/cli/src/utils/setup_files.d.ts @@ -0,0 +1,16 @@ +/** + * Ensure .github, .github/workflows and .github/ISSUE_TEMPLATE exist; create them if missing. + * @param cwd - Directory (repo root) + */ +export declare function ensureGitHubDirs(cwd: string): void; +/** + * Copy setup files from setup/ to repo (.github/ workflows, ISSUE_TEMPLATE, pull_request_template.md, .env at root). + * Skips files that already exist at destination (no overwrite). + * Logs each file copied or skipped. No-op if setup/ does not exist. + * @param cwd - Repo root + * @returns { copied, skipped } + */ +export declare function copySetupFiles(cwd: string): { + copied: number; + skipped: number; +}; diff --git a/build/cli/src/utils/task_emoji.d.ts b/build/cli/src/utils/task_emoji.d.ts new file mode 100644 index 00000000..1291586f --- /dev/null +++ b/build/cli/src/utils/task_emoji.d.ts @@ -0,0 +1 @@ +export declare function getTaskEmoji(taskId: string): string; diff --git a/build/github_action/index.js b/build/github_action/index.js index f850c69a..8c6e91fc 100644 --- a/build/github_action/index.js +++ b/build/github_action/index.js @@ -44231,7 +44231,7 @@ async function opencodeMessageWithAgentRaw(baseUrl, options) { (0, logger_1.logDebugInfo)(`OpenCode message body: agent=${options.agent}, model=${options.providerID}/${options.modelID}, parts[0].text length=${options.promptText.length}`); const base = ensureNoTrailingSlash(baseUrl); const signal = createTimeoutSignal(constants_1.OPENCODE_REQUEST_TIMEOUT_MS); - const sessionBody = { title: 'gbf' }; + const sessionBody = { title: 'copilot' }; (0, logger_1.logDebugInfo)(`OpenCode session create body: ${JSON.stringify(sessionBody)}`); const createRes = await fetch(`${base}/session`, { method: 'POST', @@ -44832,7 +44832,7 @@ This PR merges **${head}** into **${base}**. repo: repository, pull_number: pullRequest.number, body: prBody + '\n' + commitMessages.map(msg => `- ${msg}`).join('\n') + - '\n\nThis PR was automatically created by [`git-board-flow`](https://github.com/landamessenger/git-board-flow).' + '\n\nThis PR was automatically created by [`copilot`](https://github.com/vypdev/copilot).' }); const iteration = 10; if (timeout > iteration) { @@ -47148,7 +47148,7 @@ class ContentInterface { }; } get _id() { - return `git-board-flow-${this.id}`; + return `copilot-${this.id}`; } get startPattern() { if (this.visibleContent) { @@ -47349,6 +47349,7 @@ Object.defineProperty(exports, "__esModule", ({ value: true })); exports.CheckProgressUseCase = void 0; const result_1 = __nccwpck_require__(7305); const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); const issue_repository_1 = __nccwpck_require__(57); const branch_repository_1 = __nccwpck_require__(7701); const pull_request_repository_1 = __nccwpck_require__(634); @@ -47372,7 +47373,7 @@ class CheckProgressUseCase { this.aiRepository = new ai_repository_1.AiRepository(); } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const results = []; try { // Check if AI configuration is available @@ -47626,13 +47627,14 @@ const result_1 = __nccwpck_require__(7305); const project_repository_1 = __nccwpck_require__(7917); const constants_1 = __nccwpck_require__(8593); const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); class CreateReleaseUseCase { constructor() { this.taskId = 'CreateReleaseUseCase'; this.projectRepository = new project_repository_1.ProjectRepository(); } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const result = []; if (param.singleAction.version.length === 0) { (0, logger_1.logError)(`Version is not set.`); @@ -47720,13 +47722,14 @@ const result_1 = __nccwpck_require__(7305); const project_repository_1 = __nccwpck_require__(7917); const constants_1 = __nccwpck_require__(8593); const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); class CreateTagUseCase { constructor() { this.taskId = 'CreateTagUseCase'; this.projectRepository = new project_repository_1.ProjectRepository(); } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const result = []; if (param.singleAction.version.length === 0) { (0, logger_1.logError)(`Version is not set.`); @@ -47804,6 +47807,7 @@ const result_1 = __nccwpck_require__(7305); const branch_repository_1 = __nccwpck_require__(7701); const issue_repository_1 = __nccwpck_require__(57); const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); class DeployedActionUseCase { constructor() { this.taskId = 'DeployedActionUseCase'; @@ -47811,7 +47815,7 @@ class DeployedActionUseCase { this.branchRepository = new branch_repository_1.BranchRepository(); } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const result = []; try { if (!param.labels.isDeploy) { @@ -47938,16 +47942,23 @@ const issue_repository_1 = __nccwpck_require__(57); const project_repository_1 = __nccwpck_require__(7917); const result_1 = __nccwpck_require__(7305); const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); +const setup_files_1 = __nccwpck_require__(1666); class InitialSetupUseCase { constructor() { this.taskId = 'InitialSetupUseCase'; } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const results = []; const steps = []; const errors = []; try { + // 0. Setup files (.github/workflows, .github/ISSUE_TEMPLATE, pull_request_template.md, .env) + (0, logger_1.logInfo)('📋 Ensuring .github and copying setup files...'); + (0, setup_files_1.ensureGitHubDirs)(process.cwd()); + const filesResult = (0, setup_files_1.copySetupFiles)(process.cwd()); + steps.push(`✅ Setup files: ${filesResult.copied} copied, ${filesResult.skipped} already existed`); // 1. Verificar acceso a GitHub con Personal Access Token (0, logger_1.logInfo)('🔐 Checking GitHub access...'); const githubAccessResult = await this.verifyGitHubAccess(param); @@ -48085,13 +48096,14 @@ const result_1 = __nccwpck_require__(7305); const project_repository_1 = __nccwpck_require__(7917); const constants_1 = __nccwpck_require__(8593); const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); class PublishGithubActionUseCase { constructor() { this.taskId = 'PublishGithubActionUseCase'; this.projectRepository = new project_repository_1.ProjectRepository(); } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const result = []; if (param.singleAction.version.length === 0) { (0, logger_1.logError)(`Version is not set.`); @@ -48159,6 +48171,7 @@ Object.defineProperty(exports, "__esModule", ({ value: true })); exports.RecommendStepsUseCase = void 0; const result_1 = __nccwpck_require__(7305); const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); const issue_repository_1 = __nccwpck_require__(57); const ai_repository_1 = __nccwpck_require__(8307); class RecommendStepsUseCase { @@ -48168,7 +48181,7 @@ class RecommendStepsUseCase { this.aiRepository = new ai_repository_1.AiRepository(); } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const results = []; try { if (!param.ai?.getOpencodeModel() || !param.ai?.getOpencodeServerUrl()) { @@ -48245,6 +48258,7 @@ Object.defineProperty(exports, "__esModule", ({ value: true })); exports.CommitUseCase = void 0; const result_1 = __nccwpck_require__(7305); const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); const check_progress_use_case_1 = __nccwpck_require__(7744); const notify_new_commit_on_issue_use_case_1 = __nccwpck_require__(8020); const check_changes_issue_size_use_case_1 = __nccwpck_require__(5863); @@ -48254,7 +48268,7 @@ class CommitUseCase { this.taskId = 'CommitUseCase'; } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const results = []; try { if (param.commit.commits.length === 0) { @@ -48297,6 +48311,7 @@ exports.CommitUseCase = CommitUseCase; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.IssueCommentUseCase = void 0; const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); const think_use_case_1 = __nccwpck_require__(3841); const check_issue_comment_language_use_case_1 = __nccwpck_require__(465); class IssueCommentUseCase { @@ -48304,7 +48319,7 @@ class IssueCommentUseCase { this.taskId = 'IssueCommentUseCase'; } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const results = []; results.push(...await new check_issue_comment_language_use_case_1.CheckIssueCommentLanguageUseCase().invoke(param)); results.push(...await new think_use_case_1.ThinkUseCase().invoke(param)); @@ -48324,6 +48339,7 @@ exports.IssueCommentUseCase = IssueCommentUseCase; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.IssueUseCase = void 0; const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); const check_permissions_use_case_1 = __nccwpck_require__(8749); const update_title_use_case_1 = __nccwpck_require__(5107); const assign_members_to_issue_use_case_1 = __nccwpck_require__(3115); @@ -48341,7 +48357,7 @@ class IssueUseCase { this.taskId = 'IssueUseCase'; } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const results = []; const permissionResult = await new check_permissions_use_case_1.CheckPermissionsUseCase().invoke(param); const lastAction = permissionResult[permissionResult.length - 1]; @@ -48410,13 +48426,14 @@ exports.IssueUseCase = IssueUseCase; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.PullRequestReviewCommentUseCase = void 0; const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); const check_pull_request_comment_language_use_case_1 = __nccwpck_require__(7112); class PullRequestReviewCommentUseCase { constructor() { this.taskId = 'PullRequestReviewCommentUseCase'; } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const results = []; results.push(...await new check_pull_request_comment_language_use_case_1.CheckPullRequestCommentLanguageUseCase().invoke(param)); return results; @@ -48436,6 +48453,7 @@ Object.defineProperty(exports, "__esModule", ({ value: true })); exports.PullRequestUseCase = void 0; const result_1 = __nccwpck_require__(7305); const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); const update_title_use_case_1 = __nccwpck_require__(5107); const assign_members_to_issue_use_case_1 = __nccwpck_require__(3115); const assign_reviewers_to_issue_use_case_1 = __nccwpck_require__(6275); @@ -48450,7 +48468,7 @@ class PullRequestUseCase { this.taskId = 'PullRequestUseCase'; } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const results = []; try { (0, logger_1.logDebugInfo)(`PR action ${param.pullRequest.action}`); @@ -48540,6 +48558,7 @@ Object.defineProperty(exports, "__esModule", ({ value: true })); exports.SingleActionUseCase = void 0; const result_1 = __nccwpck_require__(7305); const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); const deployed_action_use_case_1 = __nccwpck_require__(8293); const publish_github_action_use_case_1 = __nccwpck_require__(9029); const create_release_use_case_1 = __nccwpck_require__(2430); @@ -48554,7 +48573,7 @@ class SingleActionUseCase { this.taskId = 'SingleActionUseCase'; } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const results = []; try { if (!param.singleAction.validSingleAction) { @@ -49241,6 +49260,7 @@ const issue_repository_1 = __nccwpck_require__(57); const project_repository_1 = __nccwpck_require__(7917); const pull_request_repository_1 = __nccwpck_require__(634); const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); class CheckChangesIssueSizeUseCase { constructor() { this.taskId = 'CheckChangesIssueSizeUseCase'; @@ -49250,7 +49270,7 @@ class CheckChangesIssueSizeUseCase { this.pullRequestRepository = new pull_request_repository_1.PullRequestRepository(); } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const result = []; try { const baseBranch = param.currentConfiguration.parentBranch ?? @@ -49336,6 +49356,7 @@ const result_1 = __nccwpck_require__(7305); const ai_repository_1 = __nccwpck_require__(8307); const constants_1 = __nccwpck_require__(8593); const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); const build_bugbot_prompt_1 = __nccwpck_require__(6339); const deduplicate_findings_1 = __nccwpck_require__(7384); const file_ignore_1 = __nccwpck_require__(3770); @@ -49353,7 +49374,7 @@ class DetectPotentialProblemsUseCase { this.aiRepository = new ai_repository_1.AiRepository(); } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const results = []; try { if (!param.ai?.getOpencodeModel() || !param.ai?.getOpencodeServerUrl()) { @@ -49454,6 +49475,7 @@ const result_1 = __nccwpck_require__(7305); const issue_repository_1 = __nccwpck_require__(57); const list_utils_1 = __nccwpck_require__(4990); const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); const execute_script_use_case_1 = __nccwpck_require__(155); class NotifyNewCommitOnIssueUseCase { constructor() { @@ -49464,7 +49486,7 @@ class NotifyNewCommitOnIssueUseCase { this.separator = '------------------------------------------------------'; } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const result = []; try { const branchName = param.commit.branch; @@ -49590,13 +49612,14 @@ exports.CheckPermissionsUseCase = void 0; const result_1 = __nccwpck_require__(7305); const project_repository_1 = __nccwpck_require__(7917); const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); class CheckPermissionsUseCase { constructor() { this.taskId = 'CheckPermissionsUseCase'; this.projectRepository = new project_repository_1.ProjectRepository(); } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const result = []; /** * If a release/hotfix issue was opened, check if author is a member of the project. @@ -49678,12 +49701,13 @@ Object.defineProperty(exports, "__esModule", ({ value: true })); exports.CommitPrefixBuilderUseCase = void 0; const result_1 = __nccwpck_require__(7305); const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); class CommitPrefixBuilderUseCase { constructor() { this.taskId = 'CommitPrefixBuilderUseCase'; } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const result = []; try { const branchName = param.commitPrefixBuilderParams.branchName; @@ -49794,13 +49818,14 @@ const result_1 = __nccwpck_require__(7305); const issue_repository_1 = __nccwpck_require__(57); const content_utils_1 = __nccwpck_require__(7873); const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); class GetHotfixVersionUseCase { constructor() { this.taskId = 'GetHotfixVersionUseCase'; this.issueRepository = new issue_repository_1.IssueRepository(); } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const result = []; try { let number = -1; @@ -49891,13 +49916,14 @@ const result_1 = __nccwpck_require__(7305); const issue_repository_1 = __nccwpck_require__(57); const content_utils_1 = __nccwpck_require__(7873); const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); class GetReleaseTypeUseCase { constructor() { this.taskId = 'GetReleaseTypeUseCase'; this.issueRepository = new issue_repository_1.IssueRepository(); } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const result = []; try { let number = -1; @@ -49977,13 +50003,14 @@ const result_1 = __nccwpck_require__(7305); const issue_repository_1 = __nccwpck_require__(57); const content_utils_1 = __nccwpck_require__(7873); const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); class GetReleaseVersionUseCase { constructor() { this.taskId = 'GetReleaseVersionUseCase'; this.issueRepository = new issue_repository_1.IssueRepository(); } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const result = []; try { let number = -1; @@ -50062,6 +50089,7 @@ const result_1 = __nccwpck_require__(7305); const issue_repository_1 = __nccwpck_require__(57); const list_utils_1 = __nccwpck_require__(4990); const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); /** * Publish the resume of actions */ @@ -50071,7 +50099,7 @@ class PublishResultUseCase { this.issueRepository = new issue_repository_1.IssueRepository(); } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); try { /** * Comment resume of actions @@ -50188,7 +50216,7 @@ ${footer} ${errors} -Check your project configuration, if everything is okay consider [opening an issue](https://github.com/landamessenger/git-board-flow/issues/new/choose). +Check your project configuration, if everything is okay consider [opening an issue](https://github.com/vypdev/copilot/issues/new/choose). `; } const commentBody = `# ${title} @@ -50245,6 +50273,7 @@ Object.defineProperty(exports, "__esModule", ({ value: true })); exports.StoreConfigurationUseCase = void 0; const configuration_handler_1 = __nccwpck_require__(4509); const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); /** * Store las configuration in the description */ @@ -50254,7 +50283,7 @@ class StoreConfigurationUseCase { this.handler = new configuration_handler_1.ConfigurationHandler(); } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); try { await this.handler.update(param); } @@ -50422,13 +50451,14 @@ exports.UpdateTitleUseCase = void 0; const result_1 = __nccwpck_require__(7305); const issue_repository_1 = __nccwpck_require__(57); const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); class UpdateTitleUseCase { constructor() { this.taskId = 'UpdateTitleUseCase'; this.issueRepository = new issue_repository_1.IssueRepository(); } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const result = []; try { if (param.isIssue) { @@ -50540,6 +50570,7 @@ const result_1 = __nccwpck_require__(7305); const issue_repository_1 = __nccwpck_require__(57); const project_repository_1 = __nccwpck_require__(7917); const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); class AssignMemberToIssueUseCase { constructor() { this.taskId = 'AssignMemberToIssueUseCase'; @@ -50547,7 +50578,7 @@ class AssignMemberToIssueUseCase { this.projectRepository = new project_repository_1.ProjectRepository(); } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const desiredAssigneesCount = param.isIssue ? param.issue.desiredAssigneesCount : param.pullRequest.desiredAssigneesCount; const number = param.isIssue ? param.issue.number : param.pullRequest.number; @@ -50661,6 +50692,7 @@ const issue_repository_1 = __nccwpck_require__(57); const project_repository_1 = __nccwpck_require__(7917); const pull_request_repository_1 = __nccwpck_require__(634); const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); class AssignReviewersToIssueUseCase { constructor() { this.taskId = 'AssignReviewersToIssueUseCase'; @@ -50669,7 +50701,7 @@ class AssignReviewersToIssueUseCase { this.projectRepository = new project_repository_1.ProjectRepository(); } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const desiredReviewersCount = param.pullRequest.desiredReviewersCount; const number = param.pullRequest.number; const result = []; @@ -50750,13 +50782,14 @@ exports.CheckPriorityIssueSizeUseCase = void 0; const result_1 = __nccwpck_require__(7305); const project_repository_1 = __nccwpck_require__(7917); const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); class CheckPriorityIssueSizeUseCase { constructor() { this.taskId = 'CheckPriorityIssueSizeUseCase'; this.projectRepository = new project_repository_1.ProjectRepository(); } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const result = []; try { const priority = param.labels.priorityLabelOnIssue; @@ -50834,13 +50867,14 @@ exports.CloseIssueAfterMergingUseCase = void 0; const result_1 = __nccwpck_require__(7305); const issue_repository_1 = __nccwpck_require__(57); const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); class CloseIssueAfterMergingUseCase { constructor() { this.taskId = 'CloseIssueAfterMergingUseCase'; this.issueRepository = new issue_repository_1.IssueRepository(); } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const result = []; try { const closed = await this.issueRepository.closeIssue(param.owner, param.repo, param.issueNumber, param.tokens.token); @@ -50892,13 +50926,14 @@ exports.CloseNotAllowedIssueUseCase = void 0; const result_1 = __nccwpck_require__(7305); const issue_repository_1 = __nccwpck_require__(57); const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); class CloseNotAllowedIssueUseCase { constructor() { this.taskId = 'CloseNotAllowedIssueUseCase'; this.issueRepository = new issue_repository_1.IssueRepository(); } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const result = []; try { const closed = await this.issueRepository.closeIssue(param.owner, param.repo, param.issueNumber, param.tokens.token); @@ -50951,6 +50986,7 @@ const result_1 = __nccwpck_require__(7305); const branch_repository_1 = __nccwpck_require__(7701); const content_utils_1 = __nccwpck_require__(7873); const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); const move_issue_to_in_progress_1 = __nccwpck_require__(8203); class DeployAddedUseCase { constructor() { @@ -50958,7 +50994,7 @@ class DeployAddedUseCase { this.branchRepository = new branch_repository_1.BranchRepository(); } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const result = []; try { if (param.issue.labeled && param.issue.labelAdded === param.labels.deploy) { @@ -51067,12 +51103,13 @@ Object.defineProperty(exports, "__esModule", ({ value: true })); exports.DeployedAddedUseCase = void 0; const result_1 = __nccwpck_require__(7305); const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); class DeployedAddedUseCase { constructor() { this.taskId = 'DeployedAddedUseCase'; } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const result = []; try { if (param.issue.labeled && param.issue.labelAdded === param.labels.deployed) { @@ -51141,6 +51178,7 @@ const result_1 = __nccwpck_require__(7305); const issue_repository_1 = __nccwpck_require__(57); const project_repository_1 = __nccwpck_require__(7917); const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); class LinkIssueProjectUseCase { constructor() { this.taskId = 'LinkIssueProjectUseCase'; @@ -51148,7 +51186,7 @@ class LinkIssueProjectUseCase { this.projectRepository = new project_repository_1.ProjectRepository(); } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const result = []; const columnName = param.project.getProjectColumnIssueCreated(); try { @@ -51213,13 +51251,14 @@ exports.MoveIssueToInProgressUseCase = void 0; const result_1 = __nccwpck_require__(7305); const project_repository_1 = __nccwpck_require__(7917); const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); class MoveIssueToInProgressUseCase { constructor() { this.taskId = 'MoveIssueToInProgressUseCase'; this.projectRepository = new project_repository_1.ProjectRepository(); } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const result = []; const columnName = param.project.getProjectColumnIssueInProgress(); try { @@ -51303,6 +51342,7 @@ const core = __importStar(__nccwpck_require__(2186)); const result_1 = __nccwpck_require__(7305); const branch_repository_1 = __nccwpck_require__(7701); const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); const execute_script_use_case_1 = __nccwpck_require__(155); const move_issue_to_in_progress_1 = __nccwpck_require__(8203); class PrepareBranchesUseCase { @@ -51311,7 +51351,7 @@ class PrepareBranchesUseCase { this.branchRepository = new branch_repository_1.BranchRepository(); } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const result = []; try { const issueTitle = param.issue.title; @@ -51571,6 +51611,7 @@ exports.RemoveIssueBranchesUseCase = void 0; const result_1 = __nccwpck_require__(7305); const branch_repository_1 = __nccwpck_require__(7701); const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); /** * Remove any branch created for this issue */ @@ -51580,7 +51621,7 @@ class RemoveIssueBranchesUseCase { this.branchRepository = new branch_repository_1.BranchRepository(); } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const results = []; try { const branchTypes = [param.branches.featureTree, param.branches.bugfixTree]; @@ -51681,13 +51722,14 @@ const core = __importStar(__nccwpck_require__(2186)); const result_1 = __nccwpck_require__(7305); const branch_repository_1 = __nccwpck_require__(7701); const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); class RemoveNotNeededBranchesUseCase { constructor() { this.taskId = 'RemoveNotNeededBranchesUseCase'; this.branchRepository = new branch_repository_1.BranchRepository(); } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const result = []; try { const issueTitle = param.issue.title; @@ -51798,13 +51840,14 @@ exports.UpdateIssueTypeUseCase = void 0; const result_1 = __nccwpck_require__(7305); const issue_repository_1 = __nccwpck_require__(57); const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); class UpdateIssueTypeUseCase { constructor() { this.taskId = 'UpdateIssueTypeUseCase'; this.issueRepository = new issue_repository_1.IssueRepository(); } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const result = []; try { await this.issueRepository.setIssueType(param.owner, param.repo, param.issueNumber, param.labels, param.issueTypes, param.tokens.token); @@ -51840,6 +51883,7 @@ const result_1 = __nccwpck_require__(7305); const ai_repository_1 = __nccwpck_require__(8307); const issue_repository_1 = __nccwpck_require__(57); const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); class CheckIssueCommentLanguageUseCase { constructor() { this.taskId = 'CheckIssueCommentLanguageUseCase'; @@ -51850,7 +51894,7 @@ If you'd like this comment to be translated again, please delete the entire comm -->`; } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const results = []; const commentBody = param.issue.commentBody; if (commentBody.length === 0 || commentBody.includes(this.translatedKey)) { @@ -51949,13 +51993,14 @@ exports.CheckPriorityPullRequestSizeUseCase = void 0; const result_1 = __nccwpck_require__(7305); const project_repository_1 = __nccwpck_require__(7917); const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); class CheckPriorityPullRequestSizeUseCase { constructor() { this.taskId = 'CheckPriorityPullRequestSizeUseCase'; this.projectRepository = new project_repository_1.ProjectRepository(); } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const result = []; try { const priority = param.labels.priorityLabelOnIssue; @@ -52067,13 +52112,14 @@ const github = __importStar(__nccwpck_require__(5438)); const result_1 = __nccwpck_require__(7305); const pull_request_repository_1 = __nccwpck_require__(634); const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); class LinkPullRequestIssueUseCase { constructor() { this.taskId = 'LinkPullRequestIssueUseCase'; this.pullRequestRepository = new pull_request_repository_1.PullRequestRepository(); } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const result = []; try { const isLinked = await this.pullRequestRepository.isLinked(github.context.payload.pull_request?.html_url ?? ''); @@ -52167,13 +52213,14 @@ exports.LinkPullRequestProjectUseCase = void 0; const result_1 = __nccwpck_require__(7305); const project_repository_1 = __nccwpck_require__(7917); const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); class LinkPullRequestProjectUseCase { constructor() { this.taskId = 'LinkPullRequestProjectUseCase'; this.projectRepository = new project_repository_1.ProjectRepository(); } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const result = []; const columnName = param.project.getProjectColumnPullRequestCreated(); try { @@ -52239,6 +52286,7 @@ exports.SyncSizeAndProgressLabelsFromIssueToPrUseCase = void 0; const result_1 = __nccwpck_require__(7305); const issue_repository_1 = __nccwpck_require__(57); const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); /** * Copies size and progress labels from the linked issue to the PR. * Used when a PR is opened so it gets the same size/progress as the issue (corner case: @@ -52250,7 +52298,7 @@ class SyncSizeAndProgressLabelsFromIssueToPrUseCase { this.issueRepository = new issue_repository_1.IssueRepository(); } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const result = []; try { if (param.issueNumber === -1) { @@ -52324,6 +52372,7 @@ const issue_repository_1 = __nccwpck_require__(57); const project_repository_1 = __nccwpck_require__(7917); const pull_request_repository_1 = __nccwpck_require__(634); const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); class UpdatePullRequestDescriptionUseCase { constructor() { this.taskId = 'UpdatePullRequestDescriptionUseCase'; @@ -52333,7 +52382,7 @@ class UpdatePullRequestDescriptionUseCase { this.projectRepository = new project_repository_1.ProjectRepository(); } async invoke(param) { - (0, logger_1.logDebugInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logDebugInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const result = []; try { const prNumber = param.pullRequest.number; @@ -52460,6 +52509,7 @@ const result_1 = __nccwpck_require__(7305); const ai_repository_1 = __nccwpck_require__(8307); const issue_repository_1 = __nccwpck_require__(57); const logger_1 = __nccwpck_require__(8836); +const task_emoji_1 = __nccwpck_require__(9785); class CheckPullRequestCommentLanguageUseCase { constructor() { this.taskId = 'CheckPullRequestCommentLanguageUseCase'; @@ -52470,7 +52520,7 @@ If you'd like this comment to be translated again, please delete the entire comm -->`; } async invoke(param) { - (0, logger_1.logInfo)(`Executing ${this.taskId}.`); + (0, logger_1.logInfo)(`${(0, task_emoji_1.getTaskEmoji)(this.taskId)} Executing ${this.taskId}.`); const results = []; const commentBody = param.pullRequest.commentBody; if (commentBody.length === 0 || commentBody.includes(this.translatedKey)) { @@ -52564,10 +52614,9 @@ exports.CheckPullRequestCommentLanguageUseCase = CheckPullRequestCommentLanguage "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.PROMPTS = exports.BUGBOT_MIN_SEVERITY = exports.BUGBOT_MAX_COMMENTS = exports.BUGBOT_MARKER_PREFIX = exports.ACTIONS = exports.ERRORS = exports.INPUT_KEYS = exports.WORKFLOW_ACTIVE_STATUSES = exports.WORKFLOW_STATUS = exports.DEFAULT_IMAGE_CONFIG = exports.OPENCODE_RETRY_DELAY_MS = exports.OPENCODE_MAX_RETRIES = exports.OPENCODE_REQUEST_TIMEOUT_MS = exports.OPENCODE_DEFAULT_MODEL = exports.REPO_URL = exports.TITLE = exports.COMMAND = void 0; -exports.COMMAND = 'giik'; -exports.TITLE = 'Giik'; -exports.REPO_URL = 'https://github.com/landamessenger/git-board-flow'; +exports.PROMPTS = exports.BUGBOT_MIN_SEVERITY = exports.BUGBOT_MAX_COMMENTS = exports.BUGBOT_MARKER_PREFIX = exports.ACTIONS = exports.ERRORS = exports.INPUT_KEYS = exports.WORKFLOW_ACTIVE_STATUSES = exports.WORKFLOW_STATUS = exports.DEFAULT_IMAGE_CONFIG = exports.OPENCODE_RETRY_DELAY_MS = exports.OPENCODE_MAX_RETRIES = exports.OPENCODE_REQUEST_TIMEOUT_MS = exports.OPENCODE_DEFAULT_MODEL = exports.REPO_URL = exports.TITLE = void 0; +exports.TITLE = 'Copilot'; +exports.REPO_URL = 'https://github.com/vypdev/copilot'; /** Default OpenCode model: provider/modelID (e.g. opencode/kimi-k2.5-free). Reuse for CLI, action and Ai fallbacks. */ exports.OPENCODE_DEFAULT_MODEL = 'opencode/kimi-k2.5-free'; /** Timeout in ms for OpenCode HTTP requests (session create, message, diff). Agent calls can be slow (e.g. plan analyzing repo). */ @@ -52931,8 +52980,8 @@ exports.ACTIONS = { DETECT_POTENTIAL_PROBLEMS: 'detect_potential_problems_action', RECOMMEND_STEPS: 'recommend_steps_action', }; -/** Hidden HTML comment prefix for bugbot findings (issue/PR comments). Format: */ -exports.BUGBOT_MARKER_PREFIX = 'gbf-bugbot'; +/** Hidden HTML comment prefix for bugbot findings (issue/PR comments). Format: */ +exports.BUGBOT_MARKER_PREFIX = 'copilot-bugbot'; /** Max number of individual bugbot comments to create per issue/PR. Excess findings get one summary comment suggesting to review locally. */ exports.BUGBOT_MAX_COMMENTS = 20; /** Minimum severity to publish (findings below this are dropped). Order: high > medium > low > info. */ @@ -53290,7 +53339,7 @@ async function startOpencodeServer(options) { (0, logger_1.logInfo)(`Starting OpenCode server at ${baseUrl} (this may take a moment on first run)...`); const child = (0, child_process_1.spawn)('npx', ['-y', 'opencode-ai', 'serve', '--port', String(port), '--hostname', hostname], { cwd, - env: { ...process.env, OPENCODE_CLIENT: 'git-board-flow' }, + env: { ...process.env, OPENCODE_CLIENT: 'copilot' }, stdio: ['ignore', 'pipe', 'pipe'], shell: false, }); @@ -53388,6 +53437,226 @@ const waitForPreviousRuns = async (params) => { exports.waitForPreviousRuns = waitForPreviousRuns; +/***/ }), + +/***/ 1666: +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { + +"use strict"; + +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || (function () { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function (o) { + var ar = []; + for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + __setModuleDefault(result, mod); + return result; + }; +})(); +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.ensureGitHubDirs = ensureGitHubDirs; +exports.copySetupFiles = copySetupFiles; +const fs = __importStar(__nccwpck_require__(7147)); +const path = __importStar(__nccwpck_require__(1017)); +const logger_1 = __nccwpck_require__(8836); +/** + * Ensure .github, .github/workflows and .github/ISSUE_TEMPLATE exist; create them if missing. + * @param cwd - Directory (repo root) + */ +function ensureGitHubDirs(cwd) { + const githubDir = path.join(cwd, '.github'); + const workflowsDir = path.join(cwd, '.github', 'workflows'); + const issueTemplateDir = path.join(cwd, '.github', 'ISSUE_TEMPLATE'); + if (!fs.existsSync(githubDir)) { + (0, logger_1.logInfo)('📁 Creating .github/...'); + fs.mkdirSync(githubDir, { recursive: true }); + } + if (!fs.existsSync(workflowsDir)) { + (0, logger_1.logInfo)('📁 Creating .github/workflows/...'); + fs.mkdirSync(workflowsDir, { recursive: true }); + } + if (!fs.existsSync(issueTemplateDir)) { + (0, logger_1.logInfo)('📁 Creating .github/ISSUE_TEMPLATE/...'); + fs.mkdirSync(issueTemplateDir, { recursive: true }); + } +} +/** + * Copy setup files from setup/ to repo (.github/ workflows, ISSUE_TEMPLATE, pull_request_template.md, .env at root). + * Skips files that already exist at destination (no overwrite). + * Logs each file copied or skipped. No-op if setup/ does not exist. + * @param cwd - Repo root + * @returns { copied, skipped } + */ +function copySetupFiles(cwd) { + const setupDir = path.join(cwd, 'setup'); + if (!fs.existsSync(setupDir)) + return { copied: 0, skipped: 0 }; + let copied = 0; + let skipped = 0; + const workflowsSrc = path.join(setupDir, 'workflows'); + const workflowsDst = path.join(cwd, '.github', 'workflows'); + if (fs.existsSync(workflowsSrc)) { + const files = fs.readdirSync(workflowsSrc).filter((f) => f.endsWith('.yml') || f.endsWith('.yaml')); + for (const f of files) { + const src = path.join(workflowsSrc, f); + const dst = path.join(workflowsDst, f); + if (fs.statSync(src).isFile()) { + if (fs.existsSync(dst)) { + (0, logger_1.logInfo)(` ⏭️ .github/workflows/${f} already exists; skipping.`); + skipped += 1; + } + else { + fs.copyFileSync(src, dst); + (0, logger_1.logInfo)(` ✅ Copied setup/workflows/${f} → .github/workflows/${f}`); + copied += 1; + } + } + } + } + const issueTemplateSrc = path.join(setupDir, 'ISSUE_TEMPLATE'); + const issueTemplateDst = path.join(cwd, '.github', 'ISSUE_TEMPLATE'); + if (fs.existsSync(issueTemplateSrc)) { + const files = fs.readdirSync(issueTemplateSrc).filter((f) => fs.statSync(path.join(issueTemplateSrc, f)).isFile()); + for (const f of files) { + const src = path.join(issueTemplateSrc, f); + const dst = path.join(issueTemplateDst, f); + if (fs.existsSync(dst)) { + (0, logger_1.logInfo)(` ⏭️ .github/ISSUE_TEMPLATE/${f} already exists; skipping.`); + skipped += 1; + } + else { + fs.copyFileSync(src, dst); + (0, logger_1.logInfo)(` ✅ Copied setup/ISSUE_TEMPLATE/${f} → .github/ISSUE_TEMPLATE/${f}`); + copied += 1; + } + } + } + const prTemplateSrc = path.join(setupDir, 'pull_request_template.md'); + const prTemplateDst = path.join(cwd, '.github', 'pull_request_template.md'); + if (fs.existsSync(prTemplateSrc)) { + if (fs.existsSync(prTemplateDst)) { + (0, logger_1.logInfo)(' ⏭️ .github/pull_request_template.md already exists; skipping.'); + skipped += 1; + } + else { + fs.copyFileSync(prTemplateSrc, prTemplateDst); + (0, logger_1.logInfo)(' ✅ Copied setup/pull_request_template.md → .github/pull_request_template.md'); + copied += 1; + } + } + const envSrc = path.join(setupDir, '.env'); + const envDst = path.join(cwd, '.env'); + if (fs.existsSync(envSrc) && fs.statSync(envSrc).isFile()) { + if (fs.existsSync(envDst)) { + (0, logger_1.logInfo)(' ⏭️ .env already exists; skipping.'); + skipped += 1; + } + else { + fs.copyFileSync(envSrc, envDst); + (0, logger_1.logInfo)(' ✅ Copied setup/.env → .env'); + copied += 1; + } + } + return { copied, skipped }; +} + + +/***/ }), + +/***/ 9785: +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.getTaskEmoji = getTaskEmoji; +/** + * Representative emoji per task for "Executing {taskId}" logs. + * Makes it easier to visually identify the step type in the action output. + */ +const TASK_EMOJI = { + // Main use cases + CommitUseCase: '📤', + IssueUseCase: '📋', + PullRequestUseCase: '🔀', + IssueCommentUseCase: '💬', + PullRequestReviewCommentUseCase: '💬', + SingleActionUseCase: '⚡', + // Issue steps + PrepareBranchesUseCase: '🌿', + CheckPermissionsUseCase: '🔐', + UpdateTitleUseCase: '✏️', + AssignMemberToIssueUseCase: '👤', + AssignReviewersToIssueUseCase: '👀', + LinkIssueProjectUseCase: '🔗', + LinkPullRequestProjectUseCase: '🔗', + LinkPullRequestIssueUseCase: '🔗', + CheckPriorityIssueSizeUseCase: '📏', + CheckPriorityPullRequestSizeUseCase: '📏', + CloseNotAllowedIssueUseCase: '🚫', + CloseIssueAfterMergingUseCase: '✅', + RemoveIssueBranchesUseCase: '🧹', + RemoveNotNeededBranchesUseCase: '🧹', + DeployAddedUseCase: '🏷️', + DeployedAddedUseCase: '🏷️', + MoveIssueToInProgressUseCase: '📥', + UpdateIssueTypeUseCase: '🏷️', + // Commit steps + NotifyNewCommitOnIssueUseCase: '📢', + CheckChangesIssueSizeUseCase: '📐', + DetectPotentialProblemsUseCase: '🔍', + // PR steps + SyncSizeAndProgressLabelsFromIssueToPrUseCase: '🔄', + UpdatePullRequestDescriptionUseCase: '✏️', + CheckIssueCommentLanguageUseCase: '🌐', + CheckPullRequestCommentLanguageUseCase: '🌐', + // Common steps + PublishResultUseCase: '📄', + StoreConfigurationUseCase: '⚙️', + GetReleaseVersionUseCase: '🏷️', + GetReleaseTypeUseCase: '🏷️', + GetHotfixVersionUseCase: '🏷️', + CommitPrefixBuilderUseCase: '📜', + ThinkUseCase: '💭', + // Actions + CheckProgressUseCase: '📊', + RecommendStepsUseCase: '💡', + CreateReleaseUseCase: '🎉', + CreateTagUseCase: '🏷️', + PublishGithubActionUseCase: '📦', + DeployedActionUseCase: '🚀', + InitialSetupUseCase: '🛠️', +}; +const DEFAULT_EMOJI = '▶️'; +function getTaskEmoji(taskId) { + return TASK_EMOJI[taskId] ?? DEFAULT_EMOJI; +} + + /***/ }), /***/ 6676: diff --git a/build/github_action/src/agent/__tests__/base_tool.test.d.ts b/build/github_action/src/agent/__tests__/base_tool.test.d.ts deleted file mode 100644 index 97f7a014..00000000 --- a/build/github_action/src/agent/__tests__/base_tool.test.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Tests for BaseTool - */ -export {}; diff --git a/build/github_action/src/agent/__tests__/budget_manager.test.d.ts b/build/github_action/src/agent/__tests__/budget_manager.test.d.ts deleted file mode 100644 index 603d68c8..00000000 --- a/build/github_action/src/agent/__tests__/budget_manager.test.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Tests for BudgetManager - */ -export {}; diff --git a/build/github_action/src/agent/__tests__/context_manager.test.d.ts b/build/github_action/src/agent/__tests__/context_manager.test.d.ts deleted file mode 100644 index 2b59f0eb..00000000 --- a/build/github_action/src/agent/__tests__/context_manager.test.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Tests for ContextManager - */ -export {}; diff --git a/build/github_action/src/agent/__tests__/context_sharing.test.d.ts b/build/github_action/src/agent/__tests__/context_sharing.test.d.ts deleted file mode 100644 index 698ebf25..00000000 --- a/build/github_action/src/agent/__tests__/context_sharing.test.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Tests for Context Sharing - */ -export {}; diff --git a/build/github_action/src/agent/__tests__/mcp_client.test.d.ts b/build/github_action/src/agent/__tests__/mcp_client.test.d.ts deleted file mode 100644 index f911b74e..00000000 --- a/build/github_action/src/agent/__tests__/mcp_client.test.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Tests for MCP Client - */ -export {}; diff --git a/build/github_action/src/agent/__tests__/mcp_manager.test.d.ts b/build/github_action/src/agent/__tests__/mcp_manager.test.d.ts deleted file mode 100644 index 2f119963..00000000 --- a/build/github_action/src/agent/__tests__/mcp_manager.test.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Tests for MCP Manager - */ -export {}; diff --git a/build/github_action/src/agent/__tests__/message_manager.test.d.ts b/build/github_action/src/agent/__tests__/message_manager.test.d.ts deleted file mode 100644 index b2cd7b25..00000000 --- a/build/github_action/src/agent/__tests__/message_manager.test.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Tests for MessageManager - */ -export {}; diff --git a/build/github_action/src/agent/__tests__/metrics_tracker.test.d.ts b/build/github_action/src/agent/__tests__/metrics_tracker.test.d.ts deleted file mode 100644 index 713b266a..00000000 --- a/build/github_action/src/agent/__tests__/metrics_tracker.test.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Tests for MetricsTracker - */ -export {}; diff --git a/build/github_action/src/agent/__tests__/response_parser.test.d.ts b/build/github_action/src/agent/__tests__/response_parser.test.d.ts deleted file mode 100644 index e23f57ba..00000000 --- a/build/github_action/src/agent/__tests__/response_parser.test.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Tests for ResponseParser - */ -export {}; diff --git a/build/github_action/src/agent/__tests__/retry_manager.test.d.ts b/build/github_action/src/agent/__tests__/retry_manager.test.d.ts deleted file mode 100644 index 06395513..00000000 --- a/build/github_action/src/agent/__tests__/retry_manager.test.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Tests for RetryManager - */ -export {}; diff --git a/build/github_action/src/agent/__tests__/session_manager.test.d.ts b/build/github_action/src/agent/__tests__/session_manager.test.d.ts deleted file mode 100644 index bc6b4113..00000000 --- a/build/github_action/src/agent/__tests__/session_manager.test.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Tests for SessionManager - */ -export {}; diff --git a/build/github_action/src/agent/__tests__/subagent_manager.test.d.ts b/build/github_action/src/agent/__tests__/subagent_manager.test.d.ts deleted file mode 100644 index 519f7016..00000000 --- a/build/github_action/src/agent/__tests__/subagent_manager.test.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Tests for SubAgent Manager - */ -export {}; diff --git a/build/github_action/src/agent/__tests__/tool_executor.test.d.ts b/build/github_action/src/agent/__tests__/tool_executor.test.d.ts deleted file mode 100644 index a8da0023..00000000 --- a/build/github_action/src/agent/__tests__/tool_executor.test.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Tests for ToolExecutor - */ -export {}; diff --git a/build/github_action/src/agent/__tests__/tool_permissions.test.d.ts b/build/github_action/src/agent/__tests__/tool_permissions.test.d.ts deleted file mode 100644 index a447c3e5..00000000 --- a/build/github_action/src/agent/__tests__/tool_permissions.test.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Tests for ToolPermissionsManager - */ -export {}; diff --git a/build/github_action/src/agent/__tests__/tool_registry.test.d.ts b/build/github_action/src/agent/__tests__/tool_registry.test.d.ts deleted file mode 100644 index 75f92c3e..00000000 --- a/build/github_action/src/agent/__tests__/tool_registry.test.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Tests for ToolRegistry - */ -export {}; diff --git a/build/github_action/src/agent/core/agent.d.ts b/build/github_action/src/agent/core/agent.d.ts deleted file mode 100644 index 05f5f731..00000000 --- a/build/github_action/src/agent/core/agent.d.ts +++ /dev/null @@ -1,112 +0,0 @@ -/** - * Agent - Main class for Agent SDK - * Similar to Anthropic's Agent SDK - * Integrated with all advanced features - */ -import { BaseTool } from '../tools/base_tool'; -import { AgentOptions, AgentResult, Message } from '../types'; -import { SubAgentManager, SubAgentOptions, Task } from './subagent_manager'; -export declare class Agent { - private options; - private messageManager; - private toolRegistry; - private toolExecutor; - private reasoningLoop; - private sessionManager; - private subAgentManager?; - private sessionId; - constructor(options: AgentOptions); - /** - * Execute query - main entry point - * Similar to Agent SDK's query() method - */ - query(prompt: string): Promise; - /** - * Continue conversation with additional prompt - */ - continue(prompt: string): Promise; - /** - * Load session - */ - loadSession(sessionId?: string): Promise; - /** - * Save session - */ - private saveSession; - /** - * Get session ID - */ - getSessionId(): string; - /** - * List all sessions - */ - listSessions(): Promise; - /** - * Delete session - */ - deleteSession(sessionId?: string): Promise; - /** - * Get message history - */ - getMessages(): Message[]; - /** - * Get message count - */ - getMessageCount(): number; - /** - * Reset agent (clear history) - */ - reset(): void; - /** - * Register a tool - */ - registerTool(tool: BaseTool): void; - /** - * Register multiple tools - */ - registerTools(tools: BaseTool[]): void; - /** - * Get available tools - */ - getAvailableTools(): string[]; - /** - * Get system prompt - */ - getSystemPrompt(): string | undefined; - /** - * Update system prompt - */ - setSystemPrompt(prompt: string): void; - /** - * Create a subagent - */ - createSubAgent(options: SubAgentOptions): Agent; - /** - * Execute multiple tasks in parallel using subagents - */ - executeParallel(tasks: Task[]): Promise>; - /** - * Coordinate agents with dependencies - */ - coordinateAgents(tasks: Array): Promise>; - /** - * Get subagent manager - */ - getSubAgentManager(): SubAgentManager | undefined; - /** - * Get subagent by name - */ - getSubAgent(name: string): Agent | undefined; - /** - * Get all subagents - */ - getAllSubAgents(): Agent[]; -} diff --git a/build/github_action/src/agent/core/budget_manager.d.ts b/build/github_action/src/agent/core/budget_manager.d.ts deleted file mode 100644 index e9b8d747..00000000 --- a/build/github_action/src/agent/core/budget_manager.d.ts +++ /dev/null @@ -1,45 +0,0 @@ -/** - * Budget Manager - * Tracks and enforces budget limits - */ -import { BudgetConfig } from '../types/agent_types'; -import { Metrics } from '../types/agent_types'; -export declare class BudgetManager { - private config; - private currentCost; - private currentTokens; - constructor(config?: BudgetConfig); - /** - * Check if budget is exceeded - */ - isExceeded(metrics: Metrics): boolean; - /** - * Check if budget warning should be shown - */ - shouldWarn(metrics: Metrics): boolean; - /** - * Get budget status - */ - getStatus(metrics: Metrics): { - exceeded: boolean; - warning: boolean; - tokenUsage?: { - used: number; - limit: number; - percent: number; - }; - costUsage?: { - used: number; - limit: number; - percent: number; - }; - }; - /** - * Log budget status - */ - logStatus(metrics: Metrics): void; - /** - * Update budget config - */ - updateConfig(config: BudgetConfig): void; -} diff --git a/build/github_action/src/agent/core/context_manager.d.ts b/build/github_action/src/agent/core/context_manager.d.ts deleted file mode 100644 index 918c6277..00000000 --- a/build/github_action/src/agent/core/context_manager.d.ts +++ /dev/null @@ -1,39 +0,0 @@ -/** - * Context Manager - * Manages conversation context and compression for long conversations - */ -import { Message } from '../types/message_types'; -export interface ContextStats { - messageCount: number; - estimatedTokens: number; - compressed: boolean; -} -export declare class ContextManager { - private maxContextLength; - private compressionEnabled; - constructor(maxContextLength?: number, compressionEnabled?: boolean); - /** - * Estimate tokens in messages (rough approximation: 1 token ≈ 4 characters) - */ - estimateTokens(messages: Message[]): number; - /** - * Check if context needs compression - */ - needsCompression(messages: Message[]): boolean; - /** - * Compress context by summarizing old messages - */ - compressContext(messages: Message[]): Message[]; - /** - * Get context statistics - */ - getStats(messages: Message[]): ContextStats; - /** - * Update max context length - */ - setMaxContextLength(length: number): void; - /** - * Enable/disable compression - */ - setCompressionEnabled(enabled: boolean): void; -} diff --git a/build/github_action/src/agent/core/context_sharing.d.ts b/build/github_action/src/agent/core/context_sharing.d.ts deleted file mode 100644 index 2651ae81..00000000 --- a/build/github_action/src/agent/core/context_sharing.d.ts +++ /dev/null @@ -1,35 +0,0 @@ -/** - * Context Sharing - * Manages sharing context between agents - */ -import { Message } from '../types'; -import { MessageManager } from './message_manager'; -export interface SharedContext { - messages: Message[]; - metadata?: Record; -} -export declare class ContextSharing { - /** - * Extract relevant messages from an agent - */ - static extractRelevantMessages(messages: Message[], maxMessages?: number): Message[]; - /** - * Share context between agents - */ - static shareContext(fromMessages: Message[], toMessageManager: MessageManager, options?: { - includeSystem?: boolean; - maxMessages?: number; - filterByRole?: ('user' | 'assistant' | 'system')[]; - }): void; - /** - * Merge contexts from multiple agents - */ - static mergeContexts(contexts: Message[][], options?: { - deduplicate?: boolean; - maxMessages?: number; - }): Message[]; - /** - * Create a summary of context for sharing - */ - static createContextSummary(messages: Message[]): string; -} diff --git a/build/github_action/src/agent/core/index.d.ts b/build/github_action/src/agent/core/index.d.ts deleted file mode 100644 index 80777f02..00000000 --- a/build/github_action/src/agent/core/index.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -/** - * Export core components - */ -export * from './message_manager'; -export * from './reasoning_loop'; -export * from './agent'; diff --git a/build/github_action/src/agent/core/message_manager.d.ts b/build/github_action/src/agent/core/message_manager.d.ts deleted file mode 100644 index 1cd6f7ae..00000000 --- a/build/github_action/src/agent/core/message_manager.d.ts +++ /dev/null @@ -1,49 +0,0 @@ -/** - * Message Manager for Agent SDK - * Manages conversation history in Anthropic Messages API format - */ -import { Message, ContentBlock } from '../types'; -import { ToolResult } from '../types'; -export declare class MessageManager { - private messages; - /** - * Add system message (only one allowed, at the beginning) - */ - addSystemMessage(content: string): void; - /** - * Add user message - */ - addUserMessage(content: string | ContentBlock[]): void; - /** - * Add assistant message - */ - addAssistantMessage(content: string | ContentBlock[]): void; - /** - * Add tool results as user message - */ - addToolResults(results: ToolResult[]): void; - /** - * Get all messages - */ - getMessages(): Message[]; - /** - * Get messages count - */ - getMessageCount(): number; - /** - * Get last message - */ - getLastMessage(): Message | undefined; - /** - * Reset message history - */ - reset(): void; - /** - * Check if has system message - */ - hasSystemMessage(): boolean; - /** - * Get system message if exists - */ - getSystemMessage(): string | undefined; -} diff --git a/build/github_action/src/agent/core/metrics_tracker.d.ts b/build/github_action/src/agent/core/metrics_tracker.d.ts deleted file mode 100644 index a3188919..00000000 --- a/build/github_action/src/agent/core/metrics_tracker.d.ts +++ /dev/null @@ -1,40 +0,0 @@ -/** - * Metrics Tracker - * Tracks tokens, costs, latency, and other metrics - */ -import { Metrics } from '../types/agent_types'; -export interface CostConfig { - inputCostPer1kTokens: number; - outputCostPer1kTokens: number; -} -export declare class MetricsTracker { - private metrics; - private startTime; - private apiCallTimes; - private costConfig?; - constructor(costConfig?: CostConfig); - /** - * Record API call with tokens and latency - */ - recordAPICall(inputTokens: number, outputTokens: number, latency: number): void; - /** - * Record tool call - */ - recordToolCall(): void; - /** - * Record error - */ - recordError(): void; - /** - * Get current metrics - */ - getMetrics(): Metrics; - /** - * Reset metrics - */ - reset(): void; - /** - * Set cost configuration - */ - setCostConfig(config: CostConfig): void; -} diff --git a/build/github_action/src/agent/core/reasoning_loop.d.ts b/build/github_action/src/agent/core/reasoning_loop.d.ts deleted file mode 100644 index a21f9e57..00000000 --- a/build/github_action/src/agent/core/reasoning_loop.d.ts +++ /dev/null @@ -1,55 +0,0 @@ -/** - * Reasoning Loop for Agent SDK - * Manages the conversation loop with tool calling - * Integrated with all advanced features: streaming, permissions, context, metrics, budget, timeouts, retry - */ -import { MessageManager } from './message_manager'; -import { ToolExecutor } from '../tools/tool_executor'; -import { AgentOptions, AgentResult } from '../types'; -export declare class ReasoningLoop { - private messageManager; - private toolExecutor; - private options; - private aiRepository; - private ai; - private permissionsManager; - private contextManager; - private metricsTracker; - private budgetManager; - private retryManager; - private sessionStartTime; - private timeoutId?; - constructor(messageManager: MessageManager, toolExecutor: ToolExecutor, options: AgentOptions); - /** - * Execute the reasoning loop - */ - execute(): Promise; - /** - * Call API with retry logic - */ - private callAPIWithRetry; - /** - * Call OpenCode API via AiRepository - */ - private callAPI; - /** - * Execute tools with timeout - */ - private executeToolsWithTimeout; - /** - * Create timeout promise - */ - private createTimeoutPromise; - /** - * Estimate input tokens (rough approximation) - */ - private estimateInputTokens; - /** - * Parse API response - */ - private parseResponse; - /** - * Create result object - */ - private createResult; -} diff --git a/build/github_action/src/agent/core/retry_manager.d.ts b/build/github_action/src/agent/core/retry_manager.d.ts deleted file mode 100644 index f12e42d4..00000000 --- a/build/github_action/src/agent/core/retry_manager.d.ts +++ /dev/null @@ -1,30 +0,0 @@ -/** - * Retry Manager - * Handles retries with exponential backoff and circuit breaker - */ -import { RetryConfig } from '../types/agent_types'; -export declare class RetryManager { - private config; - private circuitBreakerState; - private circuitBreakerFailures; - private circuitBreakerLastFailure; - private readonly circuitBreakerThreshold; - private readonly circuitBreakerTimeout; - constructor(config?: RetryConfig); - /** - * Execute function with retry logic - */ - execute(fn: () => Promise, errorHandler?: (error: any, attempt: number) => boolean): Promise; - /** - * Check if error is retryable - */ - private isRetryableError; - /** - * Sleep utility - */ - private sleep; - /** - * Reset circuit breaker - */ - resetCircuitBreaker(): void; -} diff --git a/build/github_action/src/agent/core/session_manager.d.ts b/build/github_action/src/agent/core/session_manager.d.ts deleted file mode 100644 index 9dd91646..00000000 --- a/build/github_action/src/agent/core/session_manager.d.ts +++ /dev/null @@ -1,55 +0,0 @@ -/** - * Session Manager - * Manages agent sessions with persistence - */ -import { Message } from '../types/message_types'; -import { AgentResult, Metrics } from '../types/agent_types'; -export interface SessionMetadata { - sessionId: string; - createdAt: number; - lastUpdated: number; - messageCount: number; - turnCount: number; - toolCallCount: number; - metrics?: Metrics; -} -export interface SessionData { - metadata: SessionMetadata; - messages: Message[]; -} -export declare class SessionManager { - private sessionsDir; - constructor(sessionsDir?: string); - /** - * Ensure sessions directory exists - */ - private ensureSessionsDir; - /** - * Get session file path - */ - private getSessionPath; - /** - * Save session - */ - saveSession(sessionId: string, messages: Message[], result?: AgentResult): Promise; - /** - * Load session - */ - loadSession(sessionId: string): Promise; - /** - * Delete session - */ - deleteSession(sessionId: string): Promise; - /** - * List all sessions - */ - listSessions(): Promise; - /** - * Get session creation time - */ - private getSessionCreatedAt; - /** - * Generate new session ID - */ - generateSessionId(): string; -} diff --git a/build/github_action/src/agent/core/subagent_manager.d.ts b/build/github_action/src/agent/core/subagent_manager.d.ts deleted file mode 100644 index 83f15559..00000000 --- a/build/github_action/src/agent/core/subagent_manager.d.ts +++ /dev/null @@ -1,77 +0,0 @@ -/** - * SubAgent Manager - * Manages subagents and their coordination - */ -import { Agent } from './agent'; -import { AgentOptions, AgentResult } from '../types'; -export interface SubAgentOptions { - name: string; - systemPrompt?: string; - tools?: any[]; - inheritTools?: boolean; - inheritContext?: boolean; - maxTurns?: number; - maxTokens?: number; - temperature?: number; -} -export interface Task { - name: string; - prompt: string; - systemPrompt?: string; - tools?: any[]; - options?: Partial; -} -export declare class SubAgentManager { - private subAgents; - private parentAgent; - private sharedContext; - constructor(parentAgent: Agent); - /** - * Create a subagent - */ - createSubAgent(options: SubAgentOptions): Agent; - /** - * Internal method to create subagent with options - */ - private createSubAgentWithOptions; - /** - * Execute multiple agents in parallel - */ - executeParallel(tasks: Task[]): Promise>; - /** - * Coordinate agents - execute with dependency management - */ - coordinateAgents(tasks: Array): Promise>; - /** - * Share context between subagents - */ - shareContext(fromAgentName: string, toAgentName: string): void; - /** - * Get subagent by name - */ - getSubAgent(name: string): Agent | undefined; - /** - * Get all subagents - */ - getAllSubAgents(): Agent[]; - /** - * Get subagent names - */ - getSubAgentNames(): string[]; - /** - * Remove subagent - */ - removeSubAgent(name: string): void; - /** - * Clear all subagents - */ - clear(): void; -} diff --git a/build/github_action/src/agent/core/tool_permissions.d.ts b/build/github_action/src/agent/core/tool_permissions.d.ts deleted file mode 100644 index f4d93f62..00000000 --- a/build/github_action/src/agent/core/tool_permissions.d.ts +++ /dev/null @@ -1,25 +0,0 @@ -/** - * Tool Permissions Manager - * Controls which tools the agent can use - */ -import { ToolPermissions } from '../types/agent_types'; -export declare class ToolPermissionsManager { - private permissions; - constructor(permissions?: ToolPermissions); - /** - * Check if a tool is allowed - */ - isAllowed(toolName: string): boolean; - /** - * Get all allowed tool names from a list - */ - filterAllowed(toolNames: string[]): string[]; - /** - * Update permissions - */ - updatePermissions(permissions: ToolPermissions): void; - /** - * Get current permissions - */ - getPermissions(): ToolPermissions; -} diff --git a/build/github_action/src/agent/index.d.ts b/build/github_action/src/agent/index.d.ts deleted file mode 100644 index d70c45a1..00000000 --- a/build/github_action/src/agent/index.d.ts +++ /dev/null @@ -1,20 +0,0 @@ -/** - * Agent SDK - Main exports - * Compatible with Anthropic Agent SDK interface - */ -export { Agent } from './core/agent'; -export { MessageManager } from './core/message_manager'; -export { ReasoningLoop } from './core/reasoning_loop'; -export { ToolPermissionsManager } from './core/tool_permissions'; -export { ContextManager } from './core/context_manager'; -export { SessionManager } from './core/session_manager'; -export { MetricsTracker } from './core/metrics_tracker'; -export { BudgetManager } from './core/budget_manager'; -export { RetryManager } from './core/retry_manager'; -export { BaseTool } from './tools/base_tool'; -export { ToolRegistry } from './tools/tool_registry'; -export { ToolExecutor } from './tools/tool_executor'; -export * from './types'; -export * from './utils'; -export { SubAgentManager } from './core/subagent_manager'; -export { ContextSharing } from './core/context_sharing'; diff --git a/build/github_action/src/agent/mcp/index.d.ts b/build/github_action/src/agent/mcp/index.d.ts deleted file mode 100644 index 4c7dce18..00000000 --- a/build/github_action/src/agent/mcp/index.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -/** - * MCP Module Exports - */ -export { MCPClient } from './mcp_client'; -export { MCPManager } from './mcp_manager'; -export { MCPToolWrapper } from './mcp_tool'; -export { StdioTransport, HTTPTransport, SSETransport, MCPTransport } from './mcp_transport'; -export * from './types'; diff --git a/build/github_action/src/agent/mcp/mcp_client.d.ts b/build/github_action/src/agent/mcp/mcp_client.d.ts deleted file mode 100644 index 033f96ce..00000000 --- a/build/github_action/src/agent/mcp/mcp_client.d.ts +++ /dev/null @@ -1,67 +0,0 @@ -/** - * MCP Client - * Client for Model Context Protocol - */ -import { MCPServerConfig, MCPMessage, MCPTool, MCPResource, MCPPrompt } from './types'; -export declare class MCPClient { - private transports; - private tools; - private resources; - private prompts; - /** - * Connect to an MCP server - */ - connect(config: MCPServerConfig): Promise; - /** - * Initialize MCP connection - */ - private initialize; - /** - * Load tools from MCP server - */ - private loadTools; - /** - * Load resources from MCP server - */ - private loadResources; - /** - * Load prompts from MCP server - */ - private loadPrompts; - /** - * Send request to MCP server - */ - sendRequest(serverName: string, method: string, params?: any): Promise; - /** - * Call an MCP tool - */ - callTool(serverName: string, toolName: string, input: Record): Promise; - /** - * Get all available tools - */ - getTools(): MCPTool[]; - /** - * Get tool by name - */ - getTool(serverName: string, toolName: string): MCPTool | undefined; - /** - * Get all available resources - */ - getResources(): MCPResource[]; - /** - * Get all available prompts - */ - getPrompts(): MCPPrompt[]; - /** - * Check if server is connected - */ - isConnected(serverName: string): boolean; - /** - * Disconnect from MCP server - */ - disconnect(serverName: string): Promise; - /** - * Disconnect from all servers - */ - disconnectAll(): Promise; -} diff --git a/build/github_action/src/agent/mcp/mcp_manager.d.ts b/build/github_action/src/agent/mcp/mcp_manager.d.ts deleted file mode 100644 index ba3e64b9..00000000 --- a/build/github_action/src/agent/mcp/mcp_manager.d.ts +++ /dev/null @@ -1,48 +0,0 @@ -/** - * MCP Manager - * Manages MCP connections and tool registration - */ -import { MCPClient } from './mcp_client'; -import { MCPServerConfig } from './types'; -import { ToolRegistry } from '../tools/tool_registry'; -export interface MCPConfig { - mcpServers: Record; -} -export declare class MCPManager { - private client; - private toolRegistry; - private connectedServers; - constructor(toolRegistry: ToolRegistry); - /** - * Load MCP configuration from file - */ - loadConfig(configPath?: string): Promise; - /** - * Initialize MCP connections from config - */ - initialize(configPath?: string): Promise; - /** - * Connect to an MCP server - */ - connectServer(config: MCPServerConfig): Promise; - /** - * Disconnect from an MCP server - */ - disconnectServer(serverName: string): Promise; - /** - * Get MCP client - */ - getClient(): MCPClient; - /** - * Check if server is connected - */ - isConnected(serverName: string): boolean; - /** - * Get connected servers - */ - getConnectedServers(): string[]; - /** - * Disconnect from all servers - */ - disconnectAll(): Promise; -} diff --git a/build/github_action/src/agent/mcp/mcp_tool.d.ts b/build/github_action/src/agent/mcp/mcp_tool.d.ts deleted file mode 100644 index 25cb8a0b..00000000 --- a/build/github_action/src/agent/mcp/mcp_tool.d.ts +++ /dev/null @@ -1,22 +0,0 @@ -/** - * MCP Tool - * Wrapper for MCP tools to integrate with BaseTool interface - */ -import { BaseTool } from '../tools/base_tool'; -import { MCPClient } from './mcp_client'; -import { MCPTool } from './types'; -export declare class MCPToolWrapper extends BaseTool { - private mcpClient; - private serverName; - private mcpTool; - constructor(mcpClient: MCPClient, serverName: string, mcpTool: MCPTool); - getName(): string; - getDescription(): string; - getInputSchema(): { - type: 'object'; - properties: Record; - required: string[]; - additionalProperties?: boolean; - }; - execute(input: Record): Promise; -} diff --git a/build/github_action/src/agent/mcp/mcp_transport.d.ts b/build/github_action/src/agent/mcp/mcp_transport.d.ts deleted file mode 100644 index ac854b8e..00000000 --- a/build/github_action/src/agent/mcp/mcp_transport.d.ts +++ /dev/null @@ -1,62 +0,0 @@ -/** - * MCP Transport - * Handles communication with MCP servers via different transports - */ -import { MCPMessage } from './types'; -export interface MCPTransport { - send(message: MCPMessage): Promise; - receive(): Promise; - close(): Promise; - isConnected(): boolean; -} -/** - * STDIO Transport - for local processes - */ -export declare class StdioTransport implements MCPTransport { - private command; - private args; - private env; - private process?; - private messageQueue; - private messageHandlers; - private connected; - constructor(command: string, args?: string[], env?: Record); - connect(): Promise; - send(message: MCPMessage): Promise; - receive(): Promise; - private handleMessage; - sendRequest(method: string, params?: any): Promise; - close(): Promise; - isConnected(): boolean; -} -/** - * HTTP Transport - for remote MCP servers - */ -export declare class HTTPTransport implements MCPTransport { - private url; - private headers; - private connected; - constructor(url: string, headers?: Record); - connect(): Promise; - send(message: MCPMessage): Promise; - receive(): Promise; - sendRequest(method: string, params?: any): Promise; - close(): Promise; - isConnected(): boolean; -} -/** - * SSE Transport - for Server-Sent Events - */ -export declare class SSETransport implements MCPTransport { - private url; - private headers; - private eventSource?; - private messageHandlers; - private connected; - constructor(url: string, headers?: Record); - connect(): Promise; - send(message: MCPMessage): Promise; - receive(): Promise; - close(): Promise; - isConnected(): boolean; -} diff --git a/build/github_action/src/agent/mcp/types.d.ts b/build/github_action/src/agent/mcp/types.d.ts deleted file mode 100644 index 42a702b9..00000000 --- a/build/github_action/src/agent/mcp/types.d.ts +++ /dev/null @@ -1,63 +0,0 @@ -/** - * MCP Types - * Types for Model Context Protocol - */ -export interface MCPServerConfig { - name: string; - command?: string; - args?: string[]; - env?: Record; - url?: string; - headers?: Record; - transport?: 'stdio' | 'http' | 'sse'; -} -export interface MCPMessage { - jsonrpc: '2.0'; - id?: string | number; - method?: string; - params?: any; - result?: any; - error?: MCPError; -} -export interface MCPError { - code: number; - message: string; - data?: any; -} -export interface MCPTool { - name: string; - description: string; - inputSchema: { - type: 'object'; - properties: Record; - required: string[]; - additionalProperties?: boolean; - }; -} -export interface MCPResource { - uri: string; - name: string; - description?: string; - mimeType?: string; -} -export interface MCPPrompt { - name: string; - description?: string; - arguments?: Array<{ - name: string; - description?: string; - required?: boolean; - }>; -} -export interface MCPInitializeResult { - protocolVersion: string; - capabilities: { - tools?: {}; - resources?: {}; - prompts?: {}; - }; - serverInfo: { - name: string; - version: string; - }; -} diff --git a/build/github_action/src/agent/reasoning/copilot/__tests__/copilot.test.d.ts b/build/github_action/src/agent/reasoning/copilot/__tests__/copilot.test.d.ts deleted file mode 100644 index f9fc25ff..00000000 --- a/build/github_action/src/agent/reasoning/copilot/__tests__/copilot.test.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Tests for Copilot Agent - */ -export {}; diff --git a/build/github_action/src/agent/reasoning/copilot/agent_initializer.d.ts b/build/github_action/src/agent/reasoning/copilot/agent_initializer.d.ts deleted file mode 100644 index 42d03e01..00000000 --- a/build/github_action/src/agent/reasoning/copilot/agent_initializer.d.ts +++ /dev/null @@ -1,44 +0,0 @@ -/** - * Agent Initializer - * Initializes agent with tools and repository files for Copilot - */ -import { Agent } from '../../core/agent'; -import { CopilotOptions } from './types'; -import { ReadFileTool } from '../../tools/builtin_tools/read_file_tool'; -import { SearchFilesTool } from '../../tools/builtin_tools/search_files_tool'; -import { ProposeChangeTool } from '../../tools/builtin_tools/propose_change_tool'; -import { ApplyChangesTool } from '../../tools/builtin_tools/apply_changes_tool'; -import { ExecuteCommandTool } from '../../tools/builtin_tools/execute_command_tool'; -import { ManageTodosTool } from '../../tools/builtin_tools/manage_todos_tool'; -export interface AgentInitializerResult { - agent: Agent; - repositoryFiles: Map; -} -export declare class AgentInitializer { - private static readonly EXCLUDE_PATTERNS; - private static readonly IGNORE_FILES; - /** - * Initialize agent with tools and repository files - */ - static initialize(options: CopilotOptions): Promise; - /** - * Load repository files from GitHub - */ - private static loadRepositoryFiles; - /** - * Create tools for the agent - */ - static createTools(repositoryFiles: Map, options: CopilotOptions): Promise<(ReadFileTool | SearchFilesTool | ProposeChangeTool | ManageTodosTool | ApplyChangesTool | ExecuteCommandTool)[]>; - /** - * Create ManageTodosTool - */ - private static createManageTodosTool; - /** - * Search files in repository - */ - private static searchFiles; - /** - * Get all files (excluding compiled files) - */ - private static getAllFiles; -} diff --git a/build/github_action/src/agent/reasoning/copilot/copilot.d.ts b/build/github_action/src/agent/reasoning/copilot/copilot.d.ts deleted file mode 100644 index 717453ba..00000000 --- a/build/github_action/src/agent/reasoning/copilot/copilot.d.ts +++ /dev/null @@ -1,62 +0,0 @@ -/** - * Copilot Agent - * Uses Agent SDK to provide advanced reasoning and code-manipulation capabilities - * - * Copilot can analyze, explain, answer questions about, and modify source code - * based on user-defined prompts or automated workflows. - * - * Its purpose is to act as an on-demand development assistant capable of offering - * guidance, insights, and direct code transformations across the repository. - */ -import { Agent } from '../../core/agent'; -import { CopilotOptions, CopilotResult } from './types'; -export declare class Copilot { - private agent; - private options; - private repositoryFiles; - private intentClassifier?; - constructor(options: CopilotOptions); - /** - * Process a user prompt and provide a response - * - * This method handles various types of requests: - * - Questions about code structure, functionality, or implementation - * - Requests to analyze code for issues or patterns - * - Requests to explain how code works - * - Requests to modify existing code - * - Requests to create new files or implement features - * - * @param prompt - User's prompt/question/request - * @returns CopilotResult containing the agent's response and any changes made - */ - processPrompt(prompt: string): Promise; - /** - * Determine if a prompt is complex enough to benefit from sub-agents - * - * @internal - * Complex prompts typically involve: - * - Analyzing multiple files - * - Refactoring across the codebase - * - Large-scale changes - * - Comprehensive analysis tasks - * - * @param prompt - User's prompt - * @returns true if the prompt seems complex - */ - private isComplexPrompt; - /** - * Extract changes from agent result - * - * @internal - * This method parses the agent's tool calls and results to identify any code changes - * that were proposed using the propose_change tool. - * - * @param result - Agent result containing tool calls and results - * @returns Array of changes made - */ - private extractChanges; - /** - * Get agent instance (for advanced usage) - */ - getAgent(): Agent; -} diff --git a/build/github_action/src/agent/reasoning/copilot/file_partitioner.d.ts b/build/github_action/src/agent/reasoning/copilot/file_partitioner.d.ts deleted file mode 100644 index b686830e..00000000 --- a/build/github_action/src/agent/reasoning/copilot/file_partitioner.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -/** - * File Partitioner - * Partitions files by directory for subagent distribution - */ -export declare class FilePartitioner { - /** - * Partition files by directory to keep related files together - * Tries to balance file distribution across groups - */ - static partitionFilesByDirectory(files: string[], maxGroups: number): string[][]; -} diff --git a/build/github_action/src/agent/reasoning/copilot/index.d.ts b/build/github_action/src/agent/reasoning/copilot/index.d.ts deleted file mode 100644 index 19b9a86d..00000000 --- a/build/github_action/src/agent/reasoning/copilot/index.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Copilot Agent Module - * Exports all public types and classes - */ -export { Copilot } from './copilot'; -export type { CopilotOptions, CopilotResult } from './types'; -export { SystemPromptBuilder } from './system_prompt_builder'; -export { AgentInitializer } from './agent_initializer'; -export { SubagentHandler } from './subagent_handler'; -export { FilePartitioner } from './file_partitioner'; diff --git a/build/github_action/src/agent/reasoning/copilot/subagent_handler.d.ts b/build/github_action/src/agent/reasoning/copilot/subagent_handler.d.ts deleted file mode 100644 index bcfcad9b..00000000 --- a/build/github_action/src/agent/reasoning/copilot/subagent_handler.d.ts +++ /dev/null @@ -1,60 +0,0 @@ -/** - * Subagent Handler - * Handles Copilot tasks using subagents for parallel processing - */ -import { Agent } from '../../core/agent'; -import { CopilotOptions, CopilotResult } from './types'; -export declare class SubagentHandler { - private static readonly EXCLUDE_PATTERNS; - /** - * Process prompt using subagents for parallel processing - * - * Uses a two-phase approach: - * Phase 1: Subagents work in parallel (READ-ONLY) - analyze and propose changes - * Phase 2: Coordinator agent executes changes sequentially - */ - static processPromptWithSubAgents(agent: Agent, repositoryFiles: Map, options: CopilotOptions, userPrompt: string, shouldApplyChanges?: boolean): Promise; - /** - * Create READ-ONLY tools for subagents (Phase 1) - * Only allows reading files, searching, and proposing changes (in memory) - * Does NOT allow applying changes or executing commands - */ - private static createReadOnlySubagentTools; - /** - * Extract change plans from subagent results - */ - private static extractChangePlans; - /** - * Execute changes sequentially using coordinator agent (Phase 2) - */ - private static executeChangesSequentially; - /** - * Combine results from both phases - */ - private static combinePhasesResults; - /** - * Extract changes from agent result - */ - private static extractChangesFromResult; - /** - * Create tools for subagents (DEPRECATED - kept for backward compatibility) - * @deprecated Use createReadOnlySubagentTools for Phase 1 instead - */ - private static createSubagentTools; - /** - * Create ManageTodosTool - */ - private static createManageTodosTool; - /** - * Search files in repository - */ - private static searchFiles; - /** - * Get all files (excluding compiled files) - */ - private static getAllFiles; - /** - * Combine results from all subagents - */ - private static combineSubagentResults; -} diff --git a/build/github_action/src/agent/reasoning/copilot/system_prompt_builder.d.ts b/build/github_action/src/agent/reasoning/copilot/system_prompt_builder.d.ts deleted file mode 100644 index 5a796e45..00000000 --- a/build/github_action/src/agent/reasoning/copilot/system_prompt_builder.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -/** - * System Prompt Builder - * Builds system prompts for Copilot agent - */ -import { CopilotOptions } from './types'; -export declare class SystemPromptBuilder { - /** - * Build system prompt for Copilot agent - */ - static build(options: CopilotOptions): string; -} diff --git a/build/github_action/src/agent/reasoning/copilot/types.d.ts b/build/github_action/src/agent/reasoning/copilot/types.d.ts deleted file mode 100644 index 62cd3cbb..00000000 --- a/build/github_action/src/agent/reasoning/copilot/types.d.ts +++ /dev/null @@ -1,47 +0,0 @@ -/** - * Types and interfaces for Copilot Agent - */ -import { AgentResult } from '../../types'; -import { ChangeType } from '../../../data/model/think_response'; -/** - * Options for Copilot agent - */ -export interface CopilotOptions { - model?: string; - /** OpenCode server URL (e.g. http://localhost:4096) */ - serverUrl: string; - personalAccessToken?: string; - maxTurns?: number; - repositoryOwner?: string; - repositoryName?: string; - repositoryBranch?: string; - workingDirectory?: string; - useSubAgents?: boolean; - maxConcurrentSubAgents?: number; - userPrompt?: string; - useIntentClassifier?: boolean; - shouldApplyChanges?: boolean; -} -/** - * Change plan proposed by a subagent (Phase 1: Analysis) - */ -export interface ChangePlan { - file: string; - changeType: ChangeType; - description: string; - suggestedCode: string; - reasoning: string; - proposedBy: string; -} -/** - * Result of Copilot agent execution - */ -export interface CopilotResult { - response: string; - agentResult: AgentResult; - changes?: Array<{ - file: string; - changeType: ChangeType; - description?: string; - }>; -} diff --git a/build/github_action/src/agent/reasoning/error_detector/__tests__/error_detector.test.d.ts b/build/github_action/src/agent/reasoning/error_detector/__tests__/error_detector.test.d.ts deleted file mode 100644 index c2ed763b..00000000 --- a/build/github_action/src/agent/reasoning/error_detector/__tests__/error_detector.test.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Tests for Error Detector - */ -export {}; diff --git a/build/github_action/src/agent/reasoning/error_detector/__tests__/error_parser.test.d.ts b/build/github_action/src/agent/reasoning/error_detector/__tests__/error_parser.test.d.ts deleted file mode 100644 index 887bab8a..00000000 --- a/build/github_action/src/agent/reasoning/error_detector/__tests__/error_parser.test.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Tests for Error Parser - */ -export {}; diff --git a/build/github_action/src/agent/reasoning/error_detector/__tests__/file_partitioner.test.d.ts b/build/github_action/src/agent/reasoning/error_detector/__tests__/file_partitioner.test.d.ts deleted file mode 100644 index 42c32337..00000000 --- a/build/github_action/src/agent/reasoning/error_detector/__tests__/file_partitioner.test.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Tests for File Partitioner - */ -export {}; diff --git a/build/github_action/src/agent/reasoning/error_detector/__tests__/summary_generator.test.d.ts b/build/github_action/src/agent/reasoning/error_detector/__tests__/summary_generator.test.d.ts deleted file mode 100644 index 37946029..00000000 --- a/build/github_action/src/agent/reasoning/error_detector/__tests__/summary_generator.test.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Tests for Summary Generator - */ -export {}; diff --git a/build/github_action/src/agent/reasoning/error_detector/__tests__/system_prompt_builder.test.d.ts b/build/github_action/src/agent/reasoning/error_detector/__tests__/system_prompt_builder.test.d.ts deleted file mode 100644 index b913e9f8..00000000 --- a/build/github_action/src/agent/reasoning/error_detector/__tests__/system_prompt_builder.test.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Tests for System Prompt Builder - */ -export {}; diff --git a/build/github_action/src/agent/reasoning/error_detector/agent_initializer.d.ts b/build/github_action/src/agent/reasoning/error_detector/agent_initializer.d.ts deleted file mode 100644 index 2bca7049..00000000 --- a/build/github_action/src/agent/reasoning/error_detector/agent_initializer.d.ts +++ /dev/null @@ -1,45 +0,0 @@ -/** - * Agent Initializer - * Initializes agent with tools and repository files - */ -import { Agent } from '../../core/agent'; -import { ErrorDetectionOptions } from './types'; -import { ReadFileTool } from '../../tools/builtin_tools/read_file_tool'; -import { SearchFilesTool } from '../../tools/builtin_tools/search_files_tool'; -import { ProposeChangeTool } from '../../tools/builtin_tools/propose_change_tool'; -import { ManageTodosTool } from '../../tools/builtin_tools/manage_todos_tool'; -import { ReportErrorsTool } from '../../tools/builtin_tools/report_errors_tool'; -import { DetectedError } from './types'; -export interface AgentInitializerResult { - agent: Agent; - repositoryFiles: Map; - reportedErrors: DetectedError[]; -} -export declare class AgentInitializer { - private static readonly EXCLUDE_PATTERNS; - private static readonly IGNORE_FILES; - /** - * Initialize agent with tools and repository files - */ - static initialize(options: ErrorDetectionOptions): Promise; - /** - * Load repository files from GitHub - */ - private static loadRepositoryFiles; - /** - * Create tools for the agent - */ - static createTools(repositoryFiles: Map, onErrorsReported?: (errors: DetectedError[]) => void): Promise<(ReadFileTool | SearchFilesTool | ProposeChangeTool | ManageTodosTool | ReportErrorsTool)[]>; - /** - * Create ManageTodosTool - */ - private static createManageTodosTool; - /** - * Search files in repository - */ - private static searchFiles; - /** - * Get all files (excluding compiled files) - */ - private static getAllFiles; -} diff --git a/build/github_action/src/agent/reasoning/error_detector/error_detector.d.ts b/build/github_action/src/agent/reasoning/error_detector/error_detector.d.ts deleted file mode 100644 index 3c61ba52..00000000 --- a/build/github_action/src/agent/reasoning/error_detector/error_detector.d.ts +++ /dev/null @@ -1,20 +0,0 @@ -/** - * Error Detector - * Uses Agent SDK to detect potential errors in the codebase - */ -import { Agent } from '../../core/agent'; -import { ErrorDetectionOptions, ErrorDetectionResult } from './types'; -export declare class ErrorDetector { - private agent; - private options; - private repositoryFiles; - constructor(options: ErrorDetectionOptions); - /** - * Detect errors in the codebase - */ - detectErrors(prompt?: string): Promise; - /** - * Get agent instance (for advanced usage) - */ - getAgent(): Agent; -} diff --git a/build/github_action/src/agent/reasoning/error_detector/error_parser.d.ts b/build/github_action/src/agent/reasoning/error_detector/error_parser.d.ts deleted file mode 100644 index 314e8a4e..00000000 --- a/build/github_action/src/agent/reasoning/error_detector/error_parser.d.ts +++ /dev/null @@ -1,14 +0,0 @@ -/** - * Error Parser - * Parses errors from agent results and tool calls - */ -import { AgentResult } from '../../types'; -import { DetectedError } from './types'; -export declare class ErrorParser { - /** - * Parse errors from agent result - * Only uses structured format from report_errors tool - no text parsing - * The tool already validates and cleans the data, so we just extract it directly - */ - static parseErrors(result: AgentResult): DetectedError[]; -} diff --git a/build/github_action/src/agent/reasoning/error_detector/file_partitioner.d.ts b/build/github_action/src/agent/reasoning/error_detector/file_partitioner.d.ts deleted file mode 100644 index b686830e..00000000 --- a/build/github_action/src/agent/reasoning/error_detector/file_partitioner.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -/** - * File Partitioner - * Partitions files by directory for subagent distribution - */ -export declare class FilePartitioner { - /** - * Partition files by directory to keep related files together - * Tries to balance file distribution across groups - */ - static partitionFilesByDirectory(files: string[], maxGroups: number): string[][]; -} diff --git a/build/github_action/src/agent/reasoning/error_detector/file_relationship_analyzer.d.ts b/build/github_action/src/agent/reasoning/error_detector/file_relationship_analyzer.d.ts deleted file mode 100644 index 75ef4335..00000000 --- a/build/github_action/src/agent/reasoning/error_detector/file_relationship_analyzer.d.ts +++ /dev/null @@ -1,18 +0,0 @@ -/** - * File Relationship Analyzer - * Analyzes file relationships and finds consumers/dependencies - */ -export interface FileRelationshipResult { - targetFile: string; - consumers: string[]; - dependencies: string[]; - allRelatedFiles: string[]; -} -export declare class FileRelationshipAnalyzer { - private fileImportAnalyzer; - constructor(); - /** - * Analyze relationships for a target file - */ - analyzeFileRelationships(targetFile: string, repositoryFiles: Map, includeDependencies?: boolean): FileRelationshipResult | null; -} diff --git a/build/github_action/src/agent/reasoning/error_detector/index.d.ts b/build/github_action/src/agent/reasoning/error_detector/index.d.ts deleted file mode 100644 index 1b355cc4..00000000 --- a/build/github_action/src/agent/reasoning/error_detector/index.d.ts +++ /dev/null @@ -1,13 +0,0 @@ -/** - * Error Detector Module - * Exports all public types and classes - */ -export { ErrorDetector } from './error_detector'; -export type { ErrorDetectionOptions, DetectedError, ErrorDetectionResult } from './types'; -export { ErrorParser } from './error_parser'; -export { SummaryGenerator } from './summary_generator'; -export { FilePartitioner } from './file_partitioner'; -export { SystemPromptBuilder } from './system_prompt_builder'; -export { AgentInitializer } from './agent_initializer'; -export { SubagentHandler } from './subagent_handler'; -export { FileRelationshipAnalyzer } from './file_relationship_analyzer'; diff --git a/build/github_action/src/agent/reasoning/error_detector/subagent_handler.d.ts b/build/github_action/src/agent/reasoning/error_detector/subagent_handler.d.ts deleted file mode 100644 index 66821ad3..00000000 --- a/build/github_action/src/agent/reasoning/error_detector/subagent_handler.d.ts +++ /dev/null @@ -1,29 +0,0 @@ -/** - * Subagent Handler - * Handles error detection using subagents for parallel processing - */ -import { Agent } from '../../core/agent'; -import { ErrorDetectionOptions, ErrorDetectionResult } from './types'; -export declare class SubagentHandler { - private static readonly EXCLUDE_PATTERNS; - /** - * Detect errors using subagents for parallel processing - */ - static detectErrorsWithSubAgents(agent: Agent, repositoryFiles: Map, options: ErrorDetectionOptions, userPrompt: string): Promise; - /** - * Create tools for subagents - */ - private static createSubagentTools; - /** - * Search files in repository - */ - private static searchFiles; - /** - * Get all files (excluding compiled files) - */ - private static getAllFiles; - /** - * Combine results from all subagents - */ - private static combineSubagentResults; -} diff --git a/build/github_action/src/agent/reasoning/error_detector/summary_generator.d.ts b/build/github_action/src/agent/reasoning/error_detector/summary_generator.d.ts deleted file mode 100644 index f14e553a..00000000 --- a/build/github_action/src/agent/reasoning/error_detector/summary_generator.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -/** - * Summary Generator - * Generates summaries of detected errors - */ -import { DetectedError, ErrorDetectionResult } from './types'; -export declare class SummaryGenerator { - /** - * Generate summary of detected errors - */ - static generateSummary(errors: DetectedError[]): ErrorDetectionResult['summary']; -} diff --git a/build/github_action/src/agent/reasoning/error_detector/system_prompt_builder.d.ts b/build/github_action/src/agent/reasoning/error_detector/system_prompt_builder.d.ts deleted file mode 100644 index 633fff5a..00000000 --- a/build/github_action/src/agent/reasoning/error_detector/system_prompt_builder.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -/** - * System Prompt Builder - * Builds system prompts for error detection - */ -import { ErrorDetectionOptions } from './types'; -export declare class SystemPromptBuilder { - /** - * Build system prompt for error detection - */ - static build(options: ErrorDetectionOptions): string; -} diff --git a/build/github_action/src/agent/reasoning/error_detector/types.d.ts b/build/github_action/src/agent/reasoning/error_detector/types.d.ts deleted file mode 100644 index f801a35f..00000000 --- a/build/github_action/src/agent/reasoning/error_detector/types.d.ts +++ /dev/null @@ -1,117 +0,0 @@ -/** - * Types and interfaces for Error Detector - */ -import { AgentResult } from '../../types'; -/** - * Standard issue types for code analysis - * Based on common industry standards (SonarQube, ESLint, PMD, CWE, OWASP) - */ -export declare enum IssueType { - BUG = "bug", - LOGIC_ERROR = "logic-error", - RUNTIME_ERROR = "runtime-error", - NULL_POINTER = "null-pointer", - ARRAY_BOUNDS = "array-bounds", - DIVISION_BY_ZERO = "division-by-zero", - TYPE_ERROR = "type-error", - TYPE_MISMATCH = "type-mismatch", - SECURITY_VULNERABILITY = "security-vulnerability", - SQL_INJECTION = "sql-injection", - COMMAND_INJECTION = "command-injection", - XSS = "xss", - CSRF = "csrf", - AUTHENTICATION_BYPASS = "authentication-bypass", - AUTHORIZATION_BYPASS = "authorization-bypass", - SENSITIVE_DATA_EXPOSURE = "sensitive-data-exposure", - INSECURE_DESERIALIZATION = "insecure-deserialization", - SSRF = "ssrf", - BUFFER_OVERFLOW = "buffer-overflow", - INSECURE_CRYPTO = "insecure-crypto", - WEAK_RANDOM = "weak-random", - HARDCODED_SECRET = "hardcoded-secret", - INSECURE_DEPENDENCY = "insecure-dependency", - PERFORMANCE_ISSUE = "performance-issue", - MEMORY_LEAK = "memory-leak", - RESOURCE_LEAK = "resource-leak", - INEFFICIENT_ALGORITHM = "inefficient-algorithm", - UNNECESSARY_COMPUTATION = "unnecessary-computation", - BLOCKING_OPERATION = "blocking-operation", - CODE_SMELL = "code-smell", - DEAD_CODE = "dead-code", - DUPLICATE_CODE = "duplicate-code", - HIGH_COMPLEXITY = "high-complexity", - CYCLOMATIC_COMPLEXITY = "cyclomatic-complexity", - LONG_METHOD = "long-method", - LONG_PARAMETER_LIST = "long-parameter-list", - GOD_CLASS = "god-class", - MAGIC_NUMBER = "magic-number", - MISSING_ERROR_HANDLING = "missing-error-handling", - EMPTY_CATCH_BLOCK = "empty-catch-block", - CONFIGURATION_ERROR = "configuration-error", - MISCONFIGURATION = "misconfiguration", - MISSING_CONFIGURATION = "missing-configuration", - INVALID_CONFIGURATION = "invalid-configuration", - EXPOSED_CREDENTIALS = "exposed-credentials", - INSECURE_PERMISSIONS = "insecure-permissions", - RACE_CONDITION = "race-condition", - DEADLOCK = "deadlock", - THREAD_SAFETY = "thread-safety", - UNSAFE_CONCURRENCY = "unsafe-concurrency", - DEPRECATED_API = "deprecated-api", - UNUSED_CODE = "unused-code", - UNUSED_IMPORT = "unused-import", - UNUSED_VARIABLE = "unused-variable", - UNUSED_PARAMETER = "unused-parameter", - BEST_PRACTICE_VIOLATION = "best-practice-violation", - CODING_STANDARD_VIOLATION = "coding-standard-violation", - NAMING_CONVENTION = "naming-convention", - CODE_STYLE = "code-style", - CODE_ISSUE = "code-issue" -} -/** - * Severity levels for detected errors - */ -export declare enum SeverityLevel { - CRITICAL = "critical", - HIGH = "high", - MEDIUM = "medium", - LOW = "low" -} -export interface ErrorDetectionOptions { - model?: string; - serverUrl: string; - personalAccessToken?: string; - maxTurns?: number; - repositoryOwner?: string; - repositoryName?: string; - repositoryBranch?: string; - focusAreas?: string[]; - errorTypes?: IssueType[]; - useSubAgents?: boolean; - maxConcurrentSubAgents?: number; - targetFile?: string; - analyzeOnlyTargetFile?: boolean; - includeDependencies?: boolean; -} -export interface DetectedError { - file: string; - line?: number; - type: IssueType; - severity: SeverityLevel; - description: string; - suggestion?: string; -} -export interface ErrorDetectionResult { - errors: DetectedError[]; - summary: { - total: number; - bySeverity: { - critical: number; - high: number; - medium: number; - low: number; - }; - byType: Record; - }; - agentResult: AgentResult; -} diff --git a/build/github_action/src/agent/reasoning/intent_classifier/__tests__/intent_classifier.test.d.ts b/build/github_action/src/agent/reasoning/intent_classifier/__tests__/intent_classifier.test.d.ts deleted file mode 100644 index ce169c4a..00000000 --- a/build/github_action/src/agent/reasoning/intent_classifier/__tests__/intent_classifier.test.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Tests for Intent Classifier Agent - */ -export {}; diff --git a/build/github_action/src/agent/reasoning/intent_classifier/agent_initializer.d.ts b/build/github_action/src/agent/reasoning/intent_classifier/agent_initializer.d.ts deleted file mode 100644 index 2c7d8921..00000000 --- a/build/github_action/src/agent/reasoning/intent_classifier/agent_initializer.d.ts +++ /dev/null @@ -1,24 +0,0 @@ -/** - * Agent Initializer - * Initializes agent with tools for Intent Classifier - */ -import { Agent } from '../../core/agent'; -import { IntentClassifierOptions, ConfidenceLevel } from './types'; -export interface AgentInitializerResult { - agent: Agent; - reportedIntent?: { - shouldApplyChanges: boolean; - reasoning: string; - confidence: ConfidenceLevel; - }; -} -export declare class AgentInitializer { - /** - * Initialize agent with tools - */ - static initialize(options: IntentClassifierOptions): Promise; - /** - * Create tools for the agent - */ - private static createTools; -} diff --git a/build/github_action/src/agent/reasoning/intent_classifier/index.d.ts b/build/github_action/src/agent/reasoning/intent_classifier/index.d.ts deleted file mode 100644 index b2b76e61..00000000 --- a/build/github_action/src/agent/reasoning/intent_classifier/index.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -/** - * Intent Classifier Agent - * Exports for intent classification - */ -export { IntentClassifier } from './intent_classifier'; -export { IntentClassifierOptions, IntentClassificationResult } from './types'; -export { SystemPromptBuilder } from './system_prompt_builder'; -export { IntentParser } from './intent_parser'; -export { AgentInitializer } from './agent_initializer'; diff --git a/build/github_action/src/agent/reasoning/intent_classifier/intent_classifier.d.ts b/build/github_action/src/agent/reasoning/intent_classifier/intent_classifier.d.ts deleted file mode 100644 index 86a4d148..00000000 --- a/build/github_action/src/agent/reasoning/intent_classifier/intent_classifier.d.ts +++ /dev/null @@ -1,21 +0,0 @@ -/** - * Intent Classifier Agent - * Classifies user prompts to determine if changes should be applied to disk or kept in memory - */ -import { IntentClassifierOptions, IntentClassificationResult } from './types'; -export declare class IntentClassifier { - private agent; - private options; - constructor(options: IntentClassifierOptions); - /** - * Classify user prompt to determine if changes should be applied - * @param prompt - User prompt to classify - * @returns IntentClassificationResult indicating if changes should be applied - */ - classifyIntent(prompt: string): Promise; - /** - * Fallback classification using simple heuristics if agent fails - * This is used when the parser cannot extract valid JSON from the response - */ - private fallbackClassification; -} diff --git a/build/github_action/src/agent/reasoning/intent_classifier/intent_parser.d.ts b/build/github_action/src/agent/reasoning/intent_classifier/intent_parser.d.ts deleted file mode 100644 index 7f90f325..00000000 --- a/build/github_action/src/agent/reasoning/intent_classifier/intent_parser.d.ts +++ /dev/null @@ -1,15 +0,0 @@ -/** - * Intent Parser - * Parses intent classification from agent results - * Only uses structured format from report_intent tool - no text parsing - */ -import { AgentResult } from '../../types'; -import { IntentClassificationResult } from './types'; -export declare class IntentParser { - /** - * Parse intent classification from agent result - * Only uses structured format from report_intent tool - no text parsing - * The tool already validates and cleans the data, so we just extract it directly - */ - static parseIntent(result: AgentResult): IntentClassificationResult; -} diff --git a/build/github_action/src/agent/reasoning/intent_classifier/system_prompt_builder.d.ts b/build/github_action/src/agent/reasoning/intent_classifier/system_prompt_builder.d.ts deleted file mode 100644 index 9fbc6409..00000000 --- a/build/github_action/src/agent/reasoning/intent_classifier/system_prompt_builder.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -/** - * System Prompt Builder for Intent Classifier - */ -export declare class SystemPromptBuilder { - static build(): string; -} diff --git a/build/github_action/src/agent/reasoning/intent_classifier/types.d.ts b/build/github_action/src/agent/reasoning/intent_classifier/types.d.ts deleted file mode 100644 index 68069a44..00000000 --- a/build/github_action/src/agent/reasoning/intent_classifier/types.d.ts +++ /dev/null @@ -1,20 +0,0 @@ -/** - * Types for Intent Classifier Agent - */ -import { AgentResult } from '../../types'; -export declare enum ConfidenceLevel { - HIGH = "high", - MEDIUM = "medium", - LOW = "low" -} -export interface IntentClassifierOptions { - model?: string; - serverUrl: string; - maxTurns?: number; -} -export interface IntentClassificationResult { - shouldApplyChanges: boolean; - reasoning: string; - confidence: ConfidenceLevel; - agentResult: AgentResult; -} diff --git a/build/github_action/src/agent/reasoning/progress_detector/__tests__/file_partitioner.test.d.ts b/build/github_action/src/agent/reasoning/progress_detector/__tests__/file_partitioner.test.d.ts deleted file mode 100644 index 42c32337..00000000 --- a/build/github_action/src/agent/reasoning/progress_detector/__tests__/file_partitioner.test.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Tests for File Partitioner - */ -export {}; diff --git a/build/github_action/src/agent/reasoning/progress_detector/__tests__/progress_detector.test.d.ts b/build/github_action/src/agent/reasoning/progress_detector/__tests__/progress_detector.test.d.ts deleted file mode 100644 index 81f87b46..00000000 --- a/build/github_action/src/agent/reasoning/progress_detector/__tests__/progress_detector.test.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Tests for Progress Detector - */ -export {}; diff --git a/build/github_action/src/agent/reasoning/progress_detector/__tests__/progress_parser.test.d.ts b/build/github_action/src/agent/reasoning/progress_detector/__tests__/progress_parser.test.d.ts deleted file mode 100644 index 5e00815d..00000000 --- a/build/github_action/src/agent/reasoning/progress_detector/__tests__/progress_parser.test.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Tests for Progress Parser - */ -export {}; diff --git a/build/github_action/src/agent/reasoning/progress_detector/__tests__/subagent_handler.test.d.ts b/build/github_action/src/agent/reasoning/progress_detector/__tests__/subagent_handler.test.d.ts deleted file mode 100644 index da6a2d27..00000000 --- a/build/github_action/src/agent/reasoning/progress_detector/__tests__/subagent_handler.test.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Tests for Subagent Handler - */ -export {}; diff --git a/build/github_action/src/agent/reasoning/progress_detector/__tests__/system_prompt_builder.test.d.ts b/build/github_action/src/agent/reasoning/progress_detector/__tests__/system_prompt_builder.test.d.ts deleted file mode 100644 index b913e9f8..00000000 --- a/build/github_action/src/agent/reasoning/progress_detector/__tests__/system_prompt_builder.test.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Tests for System Prompt Builder - */ -export {}; diff --git a/build/github_action/src/agent/reasoning/progress_detector/agent_initializer.d.ts b/build/github_action/src/agent/reasoning/progress_detector/agent_initializer.d.ts deleted file mode 100644 index 777ed6f0..00000000 --- a/build/github_action/src/agent/reasoning/progress_detector/agent_initializer.d.ts +++ /dev/null @@ -1,42 +0,0 @@ -/** - * Agent Initializer - * Initializes agent with tools and repository files for progress detection - */ -import { Agent } from '../../core/agent'; -import { ProgressDetectionOptions } from './types'; -import { ReadFileTool } from '../../tools/builtin_tools/read_file_tool'; -import { SearchFilesTool } from '../../tools/builtin_tools/search_files_tool'; -import { ReportProgressTool } from '../../tools/builtin_tools/report_progress_tool'; -export interface AgentInitializerResult { - agent: Agent; - repositoryFiles: Map; - reportedProgress?: { - progress: number; - summary: string; - }; -} -export declare class AgentInitializer { - private static readonly EXCLUDE_PATTERNS; - private static readonly IGNORE_FILES; - /** - * Initialize agent with tools and repository files - */ - static initialize(options: ProgressDetectionOptions): Promise; - /** - * Load repository files from GitHub - * Only loads changed files if available, otherwise loads all files from the branch - */ - private static loadRepositoryFiles; - /** - * Create tools for the agent - */ - static createTools(repositoryFiles: Map, onProgressReported?: (progress: number, summary: string) => void): Promise<(ReadFileTool | SearchFilesTool | ReportProgressTool)[]>; - /** - * Search files in repository - */ - private static searchFiles; - /** - * Get all files (excluding compiled files) - */ - private static getAllFiles; -} diff --git a/build/github_action/src/agent/reasoning/progress_detector/file_partitioner.d.ts b/build/github_action/src/agent/reasoning/progress_detector/file_partitioner.d.ts deleted file mode 100644 index b686830e..00000000 --- a/build/github_action/src/agent/reasoning/progress_detector/file_partitioner.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -/** - * File Partitioner - * Partitions files by directory for subagent distribution - */ -export declare class FilePartitioner { - /** - * Partition files by directory to keep related files together - * Tries to balance file distribution across groups - */ - static partitionFilesByDirectory(files: string[], maxGroups: number): string[][]; -} diff --git a/build/github_action/src/agent/reasoning/progress_detector/index.d.ts b/build/github_action/src/agent/reasoning/progress_detector/index.d.ts deleted file mode 100644 index 269275c8..00000000 --- a/build/github_action/src/agent/reasoning/progress_detector/index.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -/** - * Progress Detector Module - * Exports all public types and classes - */ -export { ProgressDetector } from './progress_detector'; -export type { ProgressDetectionOptions, ProgressDetectionResult } from './types'; -export { ProgressParser } from './progress_parser'; -export { SystemPromptBuilder } from './system_prompt_builder'; -export { AgentInitializer } from './agent_initializer'; -export { SubagentHandler } from './subagent_handler'; -export { FilePartitioner } from './file_partitioner'; diff --git a/build/github_action/src/agent/reasoning/progress_detector/progress_detector.d.ts b/build/github_action/src/agent/reasoning/progress_detector/progress_detector.d.ts deleted file mode 100644 index 71985369..00000000 --- a/build/github_action/src/agent/reasoning/progress_detector/progress_detector.d.ts +++ /dev/null @@ -1,20 +0,0 @@ -/** - * Progress Detector - * Uses Agent SDK to detect progress of a task based on code changes - */ -import { Agent } from '../../core/agent'; -import { ProgressDetectionOptions, ProgressDetectionResult } from './types'; -export declare class ProgressDetector { - private agent; - private options; - private repositoryFiles; - constructor(options: ProgressDetectionOptions); - /** - * Detect progress of the task - */ - detectProgress(prompt?: string): Promise; - /** - * Get agent instance (for advanced usage) - */ - getAgent(): Agent; -} diff --git a/build/github_action/src/agent/reasoning/progress_detector/progress_parser.d.ts b/build/github_action/src/agent/reasoning/progress_detector/progress_parser.d.ts deleted file mode 100644 index 9d52facd..00000000 --- a/build/github_action/src/agent/reasoning/progress_detector/progress_parser.d.ts +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Progress Parser - * Parses progress percentage from agent results - * Only uses structured format from report_progress tool - no text parsing - */ -import { AgentResult } from '../../types'; -export declare class ProgressParser { - /** - * Parse progress from agent result - * Only uses structured format from report_progress tool - no text parsing - * The tool already validates and cleans the data, so we just extract it directly - */ - static parseProgress(result: AgentResult): { - progress: number; - summary: string; - }; -} diff --git a/build/github_action/src/agent/reasoning/progress_detector/subagent_handler.d.ts b/build/github_action/src/agent/reasoning/progress_detector/subagent_handler.d.ts deleted file mode 100644 index 8fb56921..00000000 --- a/build/github_action/src/agent/reasoning/progress_detector/subagent_handler.d.ts +++ /dev/null @@ -1,30 +0,0 @@ -/** - * Subagent Handler - * Handles progress detection using subagents for parallel processing - */ -import { Agent } from '../../core/agent'; -import { ProgressDetectionOptions, ProgressDetectionResult } from './types'; -export declare class SubagentHandler { - private static readonly EXCLUDE_PATTERNS; - /** - * Detect progress using subagents for parallel processing - */ - static detectProgressWithSubAgents(agent: Agent, repositoryFiles: Map, options: ProgressDetectionOptions, userPrompt: string): Promise; - /** - * Create tools for subagents - */ - private static createSubagentTools; - /** - * Search files in repository - */ - private static searchFiles; - /** - * Get all files (excluding compiled files) - */ - private static getAllFiles; - /** - * Combine results from all subagents - * Calculates average progress and combines summaries - */ - private static combineSubagentResults; -} diff --git a/build/github_action/src/agent/reasoning/progress_detector/system_prompt_builder.d.ts b/build/github_action/src/agent/reasoning/progress_detector/system_prompt_builder.d.ts deleted file mode 100644 index 65358f31..00000000 --- a/build/github_action/src/agent/reasoning/progress_detector/system_prompt_builder.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -/** - * System Prompt Builder - * Builds system prompts for progress detection - */ -import { ProgressDetectionOptions } from './types'; -export declare class SystemPromptBuilder { - /** - * Build system prompt for progress detection - */ - static build(options: ProgressDetectionOptions): string; -} diff --git a/build/github_action/src/agent/reasoning/progress_detector/types.d.ts b/build/github_action/src/agent/reasoning/progress_detector/types.d.ts deleted file mode 100644 index 8a07fa10..00000000 --- a/build/github_action/src/agent/reasoning/progress_detector/types.d.ts +++ /dev/null @@ -1,36 +0,0 @@ -/** - * Types and interfaces for Progress Detector - */ -import { AgentResult } from '../../types'; -/** - * Options for progress detection - */ -export interface ProgressDetectionOptions { - model?: string; - serverUrl: string; - personalAccessToken?: string; - maxTurns?: number; - repositoryOwner?: string; - repositoryName?: string; - repositoryBranch?: string; - developmentBranch?: string; - issueNumber?: number; - issueDescription?: string; - changedFiles?: Array<{ - filename: string; - status: 'added' | 'modified' | 'removed' | 'renamed'; - additions?: number; - deletions?: number; - patch?: string; - }>; - useSubAgents?: boolean; - maxConcurrentSubAgents?: number; -} -/** - * Result of progress detection - */ -export interface ProgressDetectionResult { - progress: number; - summary: string; - agentResult: AgentResult; -} diff --git a/build/github_action/src/agent/tools/base_tool.d.ts b/build/github_action/src/agent/tools/base_tool.d.ts deleted file mode 100644 index 2b0ca2d2..00000000 --- a/build/github_action/src/agent/tools/base_tool.d.ts +++ /dev/null @@ -1,42 +0,0 @@ -/** - * Base class for all tools - */ -import { ToolDefinition, ToolExecutionResult } from '../types'; -export declare abstract class BaseTool { - /** - * Get tool name - */ - abstract getName(): string; - /** - * Get tool description - */ - abstract getDescription(): string; - /** - * Get input schema (JSON Schema format) - */ - abstract getInputSchema(): { - type: 'object'; - properties: Record; - required: string[]; - additionalProperties?: boolean; - }; - /** - * Execute the tool - */ - abstract execute(input: Record): Promise; - /** - * Get tool definition - */ - getDefinition(): ToolDefinition; - /** - * Validate input against schema - */ - validateInput(input: Record): { - valid: boolean; - error?: string; - }; - /** - * Execute with validation - */ - executeWithValidation(input: Record): Promise; -} diff --git a/build/github_action/src/agent/tools/builtin_tools/__tests__/apply_changes_tool.test.d.ts b/build/github_action/src/agent/tools/builtin_tools/__tests__/apply_changes_tool.test.d.ts deleted file mode 100644 index 45e39211..00000000 --- a/build/github_action/src/agent/tools/builtin_tools/__tests__/apply_changes_tool.test.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Tests for Apply Changes Tool - */ -export {}; diff --git a/build/github_action/src/agent/tools/builtin_tools/__tests__/execute_command_tool.test.d.ts b/build/github_action/src/agent/tools/builtin_tools/__tests__/execute_command_tool.test.d.ts deleted file mode 100644 index e5ddd49c..00000000 --- a/build/github_action/src/agent/tools/builtin_tools/__tests__/execute_command_tool.test.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Tests for Execute Command Tool - */ -export {}; diff --git a/build/github_action/src/agent/tools/builtin_tools/__tests__/manage_todos_tool.test.d.ts b/build/github_action/src/agent/tools/builtin_tools/__tests__/manage_todos_tool.test.d.ts deleted file mode 100644 index 5d3b4977..00000000 --- a/build/github_action/src/agent/tools/builtin_tools/__tests__/manage_todos_tool.test.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Tests for Manage TODOs Tool - */ -export {}; diff --git a/build/github_action/src/agent/tools/builtin_tools/__tests__/propose_change_tool.test.d.ts b/build/github_action/src/agent/tools/builtin_tools/__tests__/propose_change_tool.test.d.ts deleted file mode 100644 index 66952c98..00000000 --- a/build/github_action/src/agent/tools/builtin_tools/__tests__/propose_change_tool.test.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Tests for Propose Change Tool - */ -export {}; diff --git a/build/github_action/src/agent/tools/builtin_tools/__tests__/read_file_tool.test.d.ts b/build/github_action/src/agent/tools/builtin_tools/__tests__/read_file_tool.test.d.ts deleted file mode 100644 index 30538889..00000000 --- a/build/github_action/src/agent/tools/builtin_tools/__tests__/read_file_tool.test.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Tests for Read File Tool - */ -export {}; diff --git a/build/github_action/src/agent/tools/builtin_tools/__tests__/report_errors_tool.test.d.ts b/build/github_action/src/agent/tools/builtin_tools/__tests__/report_errors_tool.test.d.ts deleted file mode 100644 index e9c9cd30..00000000 --- a/build/github_action/src/agent/tools/builtin_tools/__tests__/report_errors_tool.test.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Tests for Report Errors Tool - */ -export {}; diff --git a/build/github_action/src/agent/tools/builtin_tools/__tests__/report_intent_tool.test.d.ts b/build/github_action/src/agent/tools/builtin_tools/__tests__/report_intent_tool.test.d.ts deleted file mode 100644 index 6c85aec8..00000000 --- a/build/github_action/src/agent/tools/builtin_tools/__tests__/report_intent_tool.test.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Tests for Report Intent Tool - */ -export {}; diff --git a/build/github_action/src/agent/tools/builtin_tools/__tests__/report_progress_tool.test.d.ts b/build/github_action/src/agent/tools/builtin_tools/__tests__/report_progress_tool.test.d.ts deleted file mode 100644 index fbe4547a..00000000 --- a/build/github_action/src/agent/tools/builtin_tools/__tests__/report_progress_tool.test.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Tests for Report Progress Tool - */ -export {}; diff --git a/build/github_action/src/agent/tools/builtin_tools/__tests__/search_files_tool.test.d.ts b/build/github_action/src/agent/tools/builtin_tools/__tests__/search_files_tool.test.d.ts deleted file mode 100644 index 25f9bda2..00000000 --- a/build/github_action/src/agent/tools/builtin_tools/__tests__/search_files_tool.test.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Tests for Search Files Tool - */ -export {}; diff --git a/build/github_action/src/agent/tools/builtin_tools/apply_changes_tool.d.ts b/build/github_action/src/agent/tools/builtin_tools/apply_changes_tool.d.ts deleted file mode 100644 index 70d5dd1d..00000000 --- a/build/github_action/src/agent/tools/builtin_tools/apply_changes_tool.d.ts +++ /dev/null @@ -1,170 +0,0 @@ -/** - * Apply Changes Tool - Applies proposed changes from the virtual codebase to the actual file system. - * - * This tool writes files from the virtual codebase (in-memory changes) to the actual file system. - * It only applies changes to files within the working directory for safety, preventing accidental - * modifications outside the project scope. - * - * @internal - * This tool is used after propose_change to write changes to disk. It supports both specific - * file paths and applying all pending changes. The tool includes safety checks to ensure files - * are within the working directory and handles directory creation automatically. - * - * @remarks - * - Only applies changes to files within the working directory (safety check) - * - Supports dry-run mode to preview changes without writing to disk - * - Automatically creates directories if they don't exist - * - Can apply specific files or all pending changes - * - Returns detailed summary of applied changes and any errors - * - * @example - * ```typescript - * const tool = new ApplyChangesTool({ - * getVirtualCodebase: () => new Map([['src/utils.ts', 'export function util() {}']]), - * getWorkingDirectory: () => '/project', - * onChangesApplied: (changes) => { console.log('Applied:', changes); } - * }); - * - * // Apply all pending changes - * await tool.execute({}); - * - * // Apply specific files - * await tool.execute({ file_paths: ['src/utils.ts'] }); - * - * // Dry run - * await tool.execute({ dry_run: true }); - * ``` - */ -import { BaseTool } from '../base_tool'; -/** - * Options for configuring the ApplyChangesTool. - * - * @internal - * These callbacks connect the tool to the virtual codebase and working directory management. - * - * @property getVirtualCodebase - Callback to get the virtual codebase Map (file path -> content). - * @property getWorkingDirectory - Callback to get the working directory path. - * @property onChangesApplied - Optional callback invoked when changes are successfully applied to disk. - */ -export interface ApplyChangesToolOptions { - /** - * Gets the virtual codebase Map. - * - * @internal - * This callback returns the in-memory virtual codebase containing files that have been - * modified via propose_change but not yet written to disk. - * - * @returns Map of file paths to their contents - */ - getVirtualCodebase: () => Map; - /** - * Gets the working directory path. - * - * @internal - * This callback returns the working directory where files should be written. Only files - * within this directory will be applied (safety check). - * - * @returns Working directory path - */ - getWorkingDirectory: () => string; - /** - * Optional callback invoked when changes are successfully applied. - * - * @internal - * This callback is invoked after changes are written to disk (not during dry-run). - * It receives an array of applied changes with file paths and change types. - * - * @param changes - Array of applied changes with file path and change type - */ - onChangesApplied?: (changes: Array<{ - file: string; - changeType: string; - }>) => void; -} -/** - * ApplyChangesTool - Tool for applying proposed changes from virtual codebase to file system. - * - * This tool provides a safe way to write files from the virtual codebase to disk. It includes - * safety checks to ensure files are within the working directory and supports dry-run mode. - * - * @internal - * The tool validates file paths, creates directories as needed, and handles errors gracefully. - * It only applies changes to files within the working directory to prevent accidental - * modifications outside the project scope. - */ -export declare class ApplyChangesTool extends BaseTool { - private options; - /** - * Creates a new ApplyChangesTool instance. - * - * @internal - * The options parameter provides callbacks that connect this tool to the virtual codebase - * and working directory management. - * - * @param options - Configuration object with callbacks for file operations - */ - constructor(options: ApplyChangesToolOptions); - /** - * Returns the tool name used by the agent system. - * - * @internal - * This name is used when the agent calls the tool via tool calls. - * - * @returns Tool identifier: 'apply_changes' - */ - getName(): string; - /** - * Returns the tool description shown to the agent. - * - * @internal - * This description helps the agent understand when and how to use this tool. - * It's included in the agent's available tools list. - * - * @returns Human-readable description of the tool's purpose - */ - getDescription(): string; - getInputSchema(): { - type: 'object'; - properties: Record; - required: string[]; - additionalProperties?: boolean; - }; - /** - * Executes the tool with the provided input. - * - * This method applies files from the virtual codebase to the file system. It supports - * applying specific files or all pending changes, and includes a dry-run mode for preview. - * - * @internal - * The method performs the following steps: - * 1. Determines which files to apply (specific files or all pending changes) - * 2. Filters files to only include those within the working directory (safety check) - * 3. For each file: creates directory if needed, writes file content, or previews in dry-run - * 4. Collects errors and returns summary of applied changes - * - * @param input - Tool input containing optional file_paths array and dry_run boolean - * @returns String response with summary of applied changes and any errors - * - * @remarks - * - Files outside the working directory are skipped with a warning - * - Directories are created automatically if they don't exist - * - Dry-run mode shows what would be applied without writing to disk - * - Errors for individual files don't stop processing of other files - * - Returns detailed summary including file paths and change types - * - * @example - * ```typescript - * // Apply all pending changes - * const result = await tool.execute({}); - * // Returns: "Applied 2 file(s) to disk:\n - src/utils.ts (create)\n - src/helper.ts (modify)" - * - * // Apply specific files - * const result2 = await tool.execute({ file_paths: ['src/utils.ts'] }); - * - * // Dry run - * const result3 = await tool.execute({ dry_run: true }); - * // Returns: "[DRY RUN] Would apply 2 file(s):\n - src/utils.ts (create)\n - src/helper.ts (modify)" - * ``` - */ - execute(input: Record): Promise; -} diff --git a/build/github_action/src/agent/tools/builtin_tools/execute_command_tool.d.ts b/build/github_action/src/agent/tools/builtin_tools/execute_command_tool.d.ts deleted file mode 100644 index 96d431a1..00000000 --- a/build/github_action/src/agent/tools/builtin_tools/execute_command_tool.d.ts +++ /dev/null @@ -1,167 +0,0 @@ -/** - * Execute Command Tool - Executes shell commands and returns their output. - * - * This tool allows agents to execute shell commands to verify code, run tests, compile, - * lint, or perform other operations. Commands are automatically executed in the working - * directory to ensure they run in the correct location. - * - * @internal - * This tool is used by agents to verify changes, run tests, and perform other verification - * tasks. It includes automatic working directory handling, output filtering capabilities, - * and failure detection based on output patterns. - * - * @remarks - * - Commands are automatically prefixed with 'cd working_directory &&' (if autoCd is enabled) - * - Supports output filtering (head, tail, grep) for efficiency - * - Detects failure patterns in output (error, failed, exit code, etc.) - * - Captures both stdout and stderr - * - Returns formatted output with command, working directory, exit code, and output - * - * @example - * ```typescript - * const tool = new ExecuteCommandTool({ - * getWorkingDirectory: () => '/project', - * onCommandExecuted: (cmd, success, output) => { console.log('Executed:', cmd); } - * }); - * - * // Execute a command - * await tool.execute({ command: 'npm test' }); - * - * // With output filtering - * await tool.execute({ - * command: 'npm test', - * extract_lines: { head: 50, grep: 'error' } - * }); - * ``` - */ -import { BaseTool } from '../base_tool'; -/** - * Options for configuring the ExecuteCommandTool. - * - * @internal - * These callbacks and options configure command execution behavior and provide hooks - * for monitoring command execution. - * - * @property getWorkingDirectory - Optional callback to get working directory (default: process.cwd()). - * @property onCommandExecuted - Optional callback invoked after command execution with results. - * @property autoCd - If true, automatically prepend cd command (default: true). - */ -export interface ExecuteCommandToolOptions { - /** - * Optional callback to get working directory. - * - * @internal - * This callback returns the working directory where commands should be executed. - * If not provided, defaults to process.cwd(). - * - * @returns Working directory path - */ - getWorkingDirectory?: () => string; - /** - * Optional callback invoked after command execution. - * - * @internal - * This callback is invoked after each command execution with the command, success status, - * and output. Useful for logging or monitoring command execution. - * - * @param command - The executed command - * @param success - Whether command succeeded (based on exit code and output patterns) - * @param output - Command output (stdout/stderr) - */ - onCommandExecuted?: (command: string, success: boolean, output: string) => void; - /** - * If true, automatically prepend cd command (default: true). - * - * @internal - * When enabled, commands are automatically prefixed with 'cd working_directory &&' to - * ensure they run in the correct directory. This is useful when working directory differs - * from process.cwd(). - */ - autoCd?: boolean; -} -/** - * ExecuteCommandTool - Tool for executing shell commands and returning their output. - * - * This tool provides a safe way to execute shell commands with automatic working directory - * handling, output filtering, and failure detection. - * - * @internal - * The tool handles command execution, output capture, filtering, and failure detection. - * It automatically manages working directory changes and provides formatted output for easy - * consumption by agents. - */ -export declare class ExecuteCommandTool extends BaseTool { - private options; - /** - * Creates a new ExecuteCommandTool instance. - * - * @internal - * The options parameter provides callbacks and configuration for command execution. - * - * @param options - Configuration object with callbacks and options for command execution - */ - constructor(options: ExecuteCommandToolOptions); - /** - * Returns the tool name used by the agent system. - * - * @internal - * This name is used when the agent calls the tool via tool calls. - * - * @returns Tool identifier: 'execute_command' - */ - getName(): string; - getDescription(): string; - getInputSchema(): { - type: 'object'; - properties: Record; - required: string[]; - additionalProperties?: boolean; - }; - /** - * Executes the tool with the provided input. - * - * This method executes a shell command, captures its output, applies optional filters, - * and detects failure patterns. It handles both successful and failed command execution. - * - * @internal - * The method performs the following steps: - * 1. Validates command input - * 2. Automatically prepends 'cd working_directory &&' if autoCd is enabled - * 3. Executes command with proper working directory and buffer settings - * 4. Applies output filters (grep, head, tail) if specified - * 5. Detects failure patterns in output - * 6. Formats and returns result with command details and output - * - * @param input - Tool input containing command, optional working_directory, and extract_lines - * @returns Formatted string with command details, exit code, and output - * - * @throws Error if command is missing or not a string - * - * @remarks - * - Commands are automatically executed in working directory (via autoCd or cwd option) - * - Output filtering (grep, head, tail) can be combined for efficient result processing - * - Failure detection uses pattern matching on output (error, failed, exit code, etc.) - * - Both stdout and stderr are captured - * - execSync throws on non-zero exit codes, so successful execution means exit code 0 - * - Failed commands return formatted error output with exit code and status - * - * @example - * ```typescript - * // Execute a simple command - * const result = await tool.execute({ command: 'npm test' }); - * - * // With output filtering - * const result2 = await tool.execute({ - * command: 'npm test', - * extract_lines: { head: 50, grep: 'error' } - * }); - * - * // With custom working directory - * const result3 = await tool.execute({ - * command: 'ls', - * working_directory: '/tmp' - * }); - * ``` - */ - execute(input: Record): Promise; -} diff --git a/build/github_action/src/agent/tools/builtin_tools/index.d.ts b/build/github_action/src/agent/tools/builtin_tools/index.d.ts deleted file mode 100644 index efa0dc86..00000000 --- a/build/github_action/src/agent/tools/builtin_tools/index.d.ts +++ /dev/null @@ -1,12 +0,0 @@ -/** - * Export built-in tools - */ -export * from './read_file_tool'; -export * from './search_files_tool'; -export * from './propose_change_tool'; -export * from './apply_changes_tool'; -export * from './execute_command_tool'; -export * from './manage_todos_tool'; -export * from './report_errors_tool'; -export * from './report_progress_tool'; -export * from './report_intent_tool'; diff --git a/build/github_action/src/agent/tools/builtin_tools/manage_todos_tool.d.ts b/build/github_action/src/agent/tools/builtin_tools/manage_todos_tool.d.ts deleted file mode 100644 index d4507317..00000000 --- a/build/github_action/src/agent/tools/builtin_tools/manage_todos_tool.d.ts +++ /dev/null @@ -1,255 +0,0 @@ -/** - * Manage TODOs Tool - Tool for managing TODO list items for task tracking and progress monitoring. - * - * This tool provides a structured interface for agents to manage task lists during their reasoning - * process. It allows agents to create, update, and list TODO items with different statuses - * (pending, in_progress, completed, cancelled) to track high-level tasks that may require - * multiple steps to complete. - * - * @internal - * This tool is used by reasoning agents (IntentClassifier, ErrorDetector, ProgressDetector) - * to track tasks and maintain state across multiple agent turns. It provides a structured - * way to manage task lists that persist throughout the agent's reasoning process. - * - * The tool supports three main actions: - * - CREATE: Add new TODO items (only with pending or in_progress status) - * - UPDATE: Modify existing TODO items (change status, add notes) - * - LIST: Retrieve all TODO items with their current status - * - * The tool validates all inputs and ensures type safety using TodoStatus and TodoAction enums. - * It handles three distinct actions and provides clear error messages when validation fails. - * - * @remarks - * - The tool is designed to be flexible - it accepts multiple field names for content - * (content, description, text, task) to accommodate different agent response formats - * - CREATE action only allows PENDING or IN_PROGRESS status during creation - * - UPDATE action allows all TodoStatus values including COMPLETED and CANCELLED - * - LIST action returns formatted list with emojis and status indicators - * - * @example - * ```typescript - * const tool = new ManageTodosTool({ - * createTodo: (content, status) => { return { id: 'todo_1', content, status }; }, - * updateTodo: (id, updates) => { return true; }, - * getAllTodos: () => { return []; }, - * getActiveTodos: () => { return []; } - * }); - * - * // Create a TODO - * await tool.execute({ - * action: 'create', - * content: 'Fix bug in authentication', - * status: 'pending' - * }); - * - * // Update a TODO - * await tool.execute({ - * action: 'update', - * todo_id: 'todo_1', - * status: 'in_progress', - * notes: 'Working on it' - * }); - * - * // List all TODOs - * await tool.execute({ action: 'list' }); - * ``` - */ -import { BaseTool } from '../base_tool'; -import { TodoStatus } from '../../../data/model/think_response'; -/** - * Options for configuring the ManageTodosTool. - * - * @internal - * These callbacks are provided by the agent initializer and connect the tool - * to the underlying TODO manager (ThinkTodoManager). The tool acts as a bridge - * between the agent's tool calls and the actual TODO management logic. - * - * @property createTodo - Callback to create a new TODO item. Returns the created TODO with id, content, and status. - * @property updateTodo - Callback to update an existing TODO item. Returns true if update succeeded, false if TODO not found. - * @property getAllTodos - Callback to retrieve all TODO items regardless of status. - * @property getActiveTodos - Callback to retrieve only active TODO items (pending or in_progress status). - */ -export interface ManageTodosToolOptions { - /** - * Creates a new TODO item. - * - * @internal - * When creating a TODO, only PENDING or IN_PROGRESS statuses are allowed. - * COMPLETED and CANCELLED statuses cannot be set during creation as they represent - * terminal states that should only be reached through updates. - * - * @param content - Description of the task to be done - * @param status - Optional status (defaults to PENDING). Must be PENDING or IN_PROGRESS. - * @returns Created TODO item with generated id, content, and status - */ - createTodo: (content: string, status?: TodoStatus) => { - id: string; - content: string; - status: string; - }; - /** - * Updates an existing TODO item. - * - * @internal - * Updates can change the status to any valid TodoStatus value, including COMPLETED - * and CANCELLED. Notes can be added or updated. Related files and changes can be - * linked to track which files or changes are associated with this TODO. - * - * @param id - Unique identifier of the TODO to update - * @param updates - Object containing optional status, notes, related_files, and related_changes - * @returns true if TODO was found and updated, false if TODO not found - */ - updateTodo: (id: string, updates: { - status?: TodoStatus; - notes?: string; - related_files?: string[]; - related_changes?: string[]; - }) => boolean; - /** - * Retrieves all TODO items. - * - * @internal - * Returns all TODOs regardless of status. Used for listing and overview purposes. - * - * @returns Array of all TODO items with id, content, status, and optional notes - */ - getAllTodos: () => Array<{ - id: string; - content: string; - status: string; - notes?: string; - }>; - /** - * Retrieves only active TODO items. - * - * @internal - * Active TODOs are those with PENDING or IN_PROGRESS status. COMPLETED and CANCELLED - * items are excluded. Used to show only actionable items. - * - * @returns Array of active TODO items (pending or in_progress) - */ - getActiveTodos: () => Array<{ - id: string; - content: string; - status: string; - }>; -} -/** - * ManageTodosTool - Tool for managing TODO list items. - * - * This tool provides a structured interface for agents to manage task lists during - * their reasoning process. It supports creating new tasks, updating existing ones, - * and listing all tasks with their current status. - * - * @internal - * The tool validates all inputs and ensures type safety using TodoStatus and TodoAction - * enums. It handles three distinct actions (CREATE, UPDATE, LIST) and provides clear - * error messages when validation fails. - * - * The tool is designed to be flexible - it accepts multiple field names for content - * (content, description, text, task) to accommodate different agent response formats. - */ -export declare class ManageTodosTool extends BaseTool { - private options; - /** - * Creates a new ManageTodosTool instance. - * - * @internal - * The options parameter provides callbacks that connect this tool to the underlying - * TODO manager. This separation allows the tool to be used with different TODO - * management implementations. - * - * @param options - Configuration object with callbacks for TODO operations - */ - constructor(options: ManageTodosToolOptions); - /** - * Returns the tool name used by the agent system. - * - * @internal - * This name is used when the agent calls the tool via tool calls. - * - * @returns Tool identifier: 'manage_todos' - */ - getName(): string; - /** - * Returns the tool description shown to the agent. - * - * @internal - * This description helps the agent understand when and how to use this tool. - * It's included in the agent's available tools list. - * - * @returns Human-readable description of the tool's purpose - */ - getDescription(): string; - /** - * Returns the JSON schema for tool input validation. - * - * @internal - * The schema defines the structure and validation rules for the tool's input parameters. - * It uses enums (TodoAction, TodoStatus) to ensure type safety and prevent invalid values. - * The schema is used by the agent system to validate tool calls before execution. - * - * @returns JSON schema object defining input structure and validation rules - * - * @remarks - * - action is required and must be one of: CREATE, UPDATE, LIST - * - content is required for CREATE action - * - todo_id is required for UPDATE action - * - status uses TodoStatus enum values (pending, in_progress, completed, cancelled) - * - notes is optional and only used for UPDATE action - * - additionalProperties: true allows flexibility for future extensions - */ - getInputSchema(): { - type: 'object'; - properties: Record; - required: string[]; - additionalProperties?: boolean; - }; - /** - * Executes the tool with the provided input. - * - * This method handles three distinct actions: - * 1. CREATE: Creates a new TODO item with content and optional status - * 2. UPDATE: Updates an existing TODO item (status, notes) - * 3. LIST: Returns a formatted list of all TODO items - * - * @internal - * The method validates all inputs before processing. It uses TodoAction and TodoStatus - * enums to ensure type safety. For CREATE action, it accepts multiple field names - * (content, description, text, task) for flexibility with different agent response formats. - * - * @param input - Tool input containing action and action-specific parameters - * @returns String response indicating success or error, or formatted TODO list - * - * @throws Error if action is invalid, required fields are missing, or status values are invalid - * - * @remarks - * - CREATE action: Only PENDING or IN_PROGRESS status allowed during creation - * - UPDATE action: All TodoStatus values allowed, including COMPLETED and CANCELLED - * - LIST action: Returns formatted list with emojis and status indicators - * - All actions log their execution for debugging and monitoring - * - * @example - * // Create a TODO - * const result = await tool.execute({ - * action: 'create', - * content: 'Fix bug in authentication', - * status: 'pending' - * }); - * // Returns: "TODO created: [todo_1] Fix bug in authentication (pending)" - * - * // Update a TODO - * const result2 = await tool.execute({ - * action: 'update', - * todo_id: 'todo_1', - * status: 'in_progress', - * notes: 'Working on it' - * }); - * // Returns: "TODO updated: [todo_1]" - * - * // List all TODOs - * const result3 = await tool.execute({ action: 'list' }); - * // Returns formatted list with all TODOs - */ - execute(input: Record): Promise; -} diff --git a/build/github_action/src/agent/tools/builtin_tools/propose_change_tool.d.ts b/build/github_action/src/agent/tools/builtin_tools/propose_change_tool.d.ts deleted file mode 100644 index eedd399f..00000000 --- a/build/github_action/src/agent/tools/builtin_tools/propose_change_tool.d.ts +++ /dev/null @@ -1,184 +0,0 @@ -/** - * Propose Change Tool - Proposes changes to files in the virtual codebase. - * - * This tool allows agents to propose modifications to files in the virtual codebase (in-memory - * representation). Changes can be created, modified, deleted, or refactored. The tool supports - * automatic application to disk when the user prompt is detected as an order (not a question). - * - * @internal - * This tool is used by agents to make code changes during their reasoning process. Changes are - * first applied to the virtual codebase (in-memory), and can optionally be automatically written - * to disk based on intent classification or explicit auto_apply parameter. - * - * The tool implements intelligent auto-apply detection: - * - If user prompt is an ORDER (create, write, make, build, set up, modify): auto_apply is enabled - * - If user prompt is a QUESTION (what, how, why, should, could): auto_apply is disabled - * - Explicit auto_apply parameter can override the auto-detection - * - * @remarks - * - Changes are always applied to virtual codebase first (in-memory) - * - Auto-apply to disk happens when shouldApplyChanges is true (from intent classifier or prompt analysis) - * - For clear orders: files are written to disk immediately - * - For questions/doubts: changes stay in memory for discussion - * - The tool validates all inputs and ensures type safety using ChangeType enum - * - * @example - * ```typescript - * const tool = new ProposeChangeTool({ - * applyChange: (change) => { return true; }, - * autoApplyToDisk: async (filePath) => { return true; }, - * getUserPrompt: () => 'Create a new file', - * getShouldApplyChanges: () => true - * }); - * - * // Propose a change (auto-apply will be determined automatically) - * await tool.execute({ - * file_path: 'src/utils/helper.ts', - * change_type: 'create', - * description: 'Create helper utility', - * suggested_code: 'export function helper() {}', - * reasoning: 'User requested to create this file' - * }); - * ``` - */ -import { BaseTool } from '../base_tool'; -import { ChangeType } from '../../../data/model/think_response'; -/** - * Options for configuring the ProposeChangeTool. - * - * @internal - * These callbacks connect the tool to the underlying change management system and provide - * hooks for auto-applying changes to disk when appropriate. - * - * @property applyChange - Callback to apply change to virtual codebase. Returns true if successful. - * @property onChangeApplied - Optional callback invoked when change is applied to virtual codebase. - * @property autoApplyToDisk - Optional callback to automatically write changes to disk when auto_apply is enabled. - * @property getUserPrompt - Optional callback to get original user prompt for intent detection (fallback). - * @property getShouldApplyChanges - Optional callback to get pre-classified intent from intent classifier. - */ -export interface ProposeChangeToolOptions { - applyChange: (change: { - file_path: string; - change_type: ChangeType; - description: string; - suggested_code: string; - reasoning: string; - }) => boolean; - onChangeApplied?: (change: any) => void; - autoApplyToDisk?: (filePath: string, operation?: ChangeType) => Promise; - getUserPrompt?: () => string | undefined; - getShouldApplyChanges?: () => boolean | undefined; -} -/** - * ProposeChangeTool - Tool for proposing changes to files in the virtual codebase. - * - * This tool provides a structured interface for agents to propose file modifications. Changes - * are applied to the virtual codebase (in-memory) and can optionally be automatically written - * to disk based on intent classification or explicit configuration. - * - * @internal - * The tool validates all inputs and ensures type safety using ChangeType enum. It implements - * intelligent auto-apply detection based on user prompt analysis or pre-classified intent. - */ -export declare class ProposeChangeTool extends BaseTool { - private options; - /** - * Creates a new ProposeChangeTool instance. - * - * @internal - * The options parameter provides callbacks that connect this tool to the underlying change - * management system and enable auto-apply functionality. - * - * @param options - Configuration object with callbacks for change operations - */ - constructor(options: ProposeChangeToolOptions); - /** - * Returns the tool name used by the agent system. - * - * @internal - * This name is used when the agent calls the tool via tool calls. - * - * @returns Tool identifier: 'propose_change' - */ - getName(): string; - getDescription(): string; - getInputSchema(): { - type: 'object'; - properties: Record; - required: string[]; - additionalProperties?: boolean; - }; - /** - * Detects if user prompt is an order (not a question). - * - * This method analyzes the user prompt to determine if it represents a clear instruction - * to perform an action (order) versus a question seeking information. - * - * @internal - * This is a fallback method used when intent classifier is not available. It uses pattern - * matching to identify order indicators (create, write, make, build, etc.) and question - * indicators (what, how, why, ?, etc.). Question indicators take priority - if a prompt - * contains both, it's treated as a question. - * - * @param prompt - Optional user prompt to analyze - * @returns true if prompt is detected as an order, false if it's a question or unclear - * - * @remarks - * - Strong question indicators (?, what, how, why, etc.) take priority over order indicators - * - Order indicators include: create, write, make, build, set up, modify, add, implement, etc. - * - If prompt contains question mark or starts with question words, it's treated as a question - * - Default behavior: if no question mark and has action verbs, treat as order - */ - private isOrderPrompt; - /** - * Executes the tool with the provided input. - * - * This method handles the complete change proposal workflow: - * 1. Validates all input parameters (file_path, change_type, description, suggested_code, reasoning) - * 2. Applies change to virtual codebase (in-memory) - * 3. Determines if auto-apply to disk should be enabled (explicit parameter, intent classifier, or prompt analysis) - * 4. Optionally writes changes to disk if auto-apply is enabled - * - * @internal - * The method validates all inputs before processing. It uses ChangeType enum to ensure - * type safety. Auto-apply detection follows a priority order: - * 1. Explicit auto_apply parameter (if provided) - * 2. Pre-classified intent from intent classifier (if available) - * 3. Fallback to user prompt analysis (if classifier not used) - * - * @param input - Tool input containing file_path, change_type, description, suggested_code, reasoning, and optional auto_apply - * @returns String response indicating success or error, including whether changes were auto-applied to disk - * - * @throws Error if required fields are missing, change_type is invalid, or file operations fail - * - * @remarks - * - All changes are applied to virtual codebase first (in-memory) - * - Auto-apply to disk only happens if shouldAutoApply is true and autoApplyToDisk callback is provided - * - For DELETE operations, special handling is required when writing to disk - * - If auto-apply fails, the change remains in virtual codebase and user can use apply_changes tool manually - * - * @example - * ```typescript - * // Propose a change (auto-apply determined automatically) - * const result = await tool.execute({ - * file_path: 'src/utils/helper.ts', - * change_type: 'create', - * description: 'Create helper utility', - * suggested_code: 'export function helper() {}', - * reasoning: 'User requested to create this file' - * }); - * // Returns: "Change proposed and automatically applied to disk: src/utils/helper.ts: Create helper utility" - * - * // Propose a change with explicit auto_apply - * const result2 = await tool.execute({ - * file_path: 'src/utils/helper.ts', - * change_type: 'modify', - * description: 'Update helper function', - * suggested_code: 'export function helper() { return true; }', - * reasoning: 'Add return value', - * auto_apply: true - * }); - * ``` - */ - execute(input: Record): Promise; -} diff --git a/build/github_action/src/agent/tools/builtin_tools/read_file_tool.d.ts b/build/github_action/src/agent/tools/builtin_tools/read_file_tool.d.ts deleted file mode 100644 index d885fd5f..00000000 --- a/build/github_action/src/agent/tools/builtin_tools/read_file_tool.d.ts +++ /dev/null @@ -1,141 +0,0 @@ -/** - * Read File Tool - Reads file contents from repository or virtual codebase. - * - * This tool allows agents to read and examine file contents from either the virtual codebase - * (in-memory changes) or the original repository files. It provides a unified interface for - * accessing file content regardless of whether the file has been modified in the virtual codebase. - * - * @internal - * This tool is used by agents to examine code, configuration files, or any file in the codebase - * during their reasoning process. It checks the virtual codebase first (for modified files) and - * falls back to repository files if not found. - * - * @remarks - * - Virtual codebase is checked first (for files modified via propose_change) - * - Falls back to repository files if not found in virtual codebase - * - Returns formatted response with file path, line count, and code block - * - Returns error message if file is not found in either location - * - * @example - * ```typescript - * const tool = new ReadFileTool({ - * getFileContent: (filePath) => { return 'file content'; }, - * repositoryFiles: new Map([['src/utils.ts', 'export function util() {}']]) - * }); - * - * const result = await tool.execute({ file_path: 'src/utils.ts' }); - * // Returns: "File: src/utils.ts\nLines: 1\n\n```\nfile content\n```" - * ``` - */ -import { BaseTool } from '../base_tool'; -/** - * Options for configuring the ReadFileTool. - * - * @internal - * These callbacks connect the tool to the virtual codebase and repository file storage. - * - * @property getFileContent - Callback to get file content from virtual codebase. Returns content or undefined. - * @property repositoryFiles - Optional Map of repository file paths to their contents (original files). - */ -export interface ReadFileToolOptions { - /** - * Gets file content from virtual codebase. - * - * @internal - * This callback is used to retrieve file content from the in-memory virtual codebase, - * which contains files that have been modified via propose_change but not yet written to disk. - * - * @param filePath - Path to the file to read - * @returns File content as string, or undefined if file not found in virtual codebase - */ - getFileContent: (filePath: string) => string | undefined; - /** - * Optional Map of repository file paths to their contents. - * - * @internal - * This Map contains the original repository files. It's used as a fallback when - * a file is not found in the virtual codebase. - */ - repositoryFiles?: Map; -} -/** - * ReadFileTool - Tool for reading file contents from repository or virtual codebase. - * - * This tool provides a unified interface for accessing file content from either the virtual - * codebase (modified files) or the original repository files. - * - * @internal - * The tool checks the virtual codebase first, then falls back to repository files. This ensures - * that agents always see the most recent changes (from propose_change) when reading files. - */ -export declare class ReadFileTool extends BaseTool { - private options; - /** - * Creates a new ReadFileTool instance. - * - * @internal - * The options parameter provides callbacks that connect this tool to the virtual codebase - * and repository file storage. - * - * @param options - Configuration object with callbacks for file operations - */ - constructor(options: ReadFileToolOptions); - /** - * Returns the tool name used by the agent system. - * - * @internal - * This name is used when the agent calls the tool via tool calls. - * - * @returns Tool identifier: 'read_file' - */ - getName(): string; - /** - * Returns the tool description shown to the agent. - * - * @internal - * This description helps the agent understand when and how to use this tool. - * It's included in the agent's available tools list. - * - * @returns Human-readable description of the tool's purpose - */ - getDescription(): string; - getInputSchema(): { - type: 'object'; - properties: Record; - required: string[]; - additionalProperties?: boolean; - }; - /** - * Executes the tool with the provided input. - * - * This method reads file content from either the virtual codebase or repository files. - * It checks the virtual codebase first (for modified files) and falls back to repository - * files if not found. - * - * @internal - * The method validates the file_path input and then attempts to retrieve the file content - * from two sources in order: - * 1. Virtual codebase (via getFileContent callback) - contains files modified via propose_change - * 2. Repository files (via repositoryFiles Map) - contains original files - * - * @param input - Tool input containing file_path - * @returns Formatted string with file path, line count, and code block, or error message if file not found - * - * @throws Error if file_path is missing or not a string - * - * @remarks - * - Virtual codebase is checked first to ensure agents see the most recent changes - * - Response format includes file path, line count, and code block for easy reading - * - Returns error message (not exception) if file is not found in either location - * - * @example - * ```typescript - * const result = await tool.execute({ file_path: 'src/utils.ts' }); - * // Returns: "File: src/utils.ts\nLines: 10\n\n```\nexport function util() {}\n```" - * - * const result2 = await tool.execute({ file_path: 'nonexistent.ts' }); - * // Returns: "Error: File "nonexistent.ts" not found in the repository." - * ``` - */ - execute(input: Record): Promise; -} diff --git a/build/github_action/src/agent/tools/builtin_tools/report_errors_tool.d.ts b/build/github_action/src/agent/tools/builtin_tools/report_errors_tool.d.ts deleted file mode 100644 index 12ccd904..00000000 --- a/build/github_action/src/agent/tools/builtin_tools/report_errors_tool.d.ts +++ /dev/null @@ -1,152 +0,0 @@ -/** - * Report Errors Tool - Tool for reporting detected errors in structured format. - * - * This tool allows agents to report detected errors, bugs, vulnerabilities, or issues in a - * structured format. Each error includes file path, line number (if applicable), type, severity, - * description, and optional suggestion for fixing it. - * - * @internal - * This tool is used by the ErrorDetector agent to report all errors found during code analysis. - * The tool validates and cleans error data to ensure consistency, removing markdown formatting - * and normalizing values according to IssueType and SeverityLevel enums. - * - * @remarks - * - Errors must be provided as an array of plain JSON objects - * - File paths and types are cleaned to remove markdown formatting - * - IssueType values are validated and normalized (fallback to CODE_ISSUE if invalid) - * - SeverityLevel values must be one of: critical, high, medium, low - * - Descriptions and suggestions can contain newlines but no markdown formatting - * - Line numbers are optional and parsed from strings if needed - * - * @example - * ```typescript - * const tool = new ReportErrorsTool({ - * onErrorsReported: (errors) => { console.log('Errors reported:', errors); } - * }); - * - * await tool.execute({ - * errors: [ - * { - * file: 'src/utils.ts', - * line: 42, - * type: 'bug', - * severity: 'high', - * description: 'Null pointer exception possible', - * suggestion: 'Add null check before accessing property' - * } - * ] - * }); - * ``` - */ -import { BaseTool } from '../base_tool'; -import { DetectedError } from '../../reasoning/error_detector/types'; -/** - * Options for configuring the ReportErrorsTool. - * - * @internal - * The callback connects the tool to the error reporting system, allowing errors to be - * processed and stored after validation and cleaning. - * - * @property onErrorsReported - Callback invoked with cleaned and validated errors array. - */ -export interface ReportErrorsToolOptions { - /** - * Callback invoked when errors are reported. - * - * @internal - * This callback receives the cleaned and validated errors array. Errors have been - * normalized, markdown removed, and validated against IssueType and SeverityLevel enums. - * - * @param errors - Array of cleaned and validated DetectedError objects - */ - onErrorsReported: (errors: DetectedError[]) => void; -} -/** - * ReportErrorsTool - Tool for reporting detected errors in structured format. - * - * This tool provides a structured interface for agents to report errors found during code - * analysis. It validates, cleans, and normalizes error data before passing it to the callback. - * - * @internal - * The tool performs extensive cleaning and validation: - * - Removes markdown formatting from file paths, types, descriptions, and suggestions - * - Validates IssueType values (with fallback to CODE_ISSUE if invalid) - * - Validates SeverityLevel values (must be one of: critical, high, medium, low) - * - Parses line numbers from strings if needed - * - Extracts first error from concatenated error descriptions - */ -export declare class ReportErrorsTool extends BaseTool { - private options; - /** - * Creates a new ReportErrorsTool instance. - * - * @internal - * The options parameter provides the callback that receives cleaned and validated errors. - * - * @param options - Configuration object with callback for error reporting - */ - constructor(options: ReportErrorsToolOptions); - /** - * Returns the tool name used by the agent system. - * - * @internal - * This name is used when the agent calls the tool via tool calls. - * - * @returns Tool identifier: 'report_errors' - */ - getName(): string; - getDescription(): string; - getInputSchema(): { - type: 'object'; - properties: Record; - required: string[]; - additionalProperties?: boolean; - }; - /** - * Executes the tool with the provided input. - * - * This method processes an array of errors, validates and cleans each error, and then - * passes the cleaned errors to the callback. The cleaning process removes markdown - * formatting, normalizes values, and validates against IssueType and SeverityLevel enums. - * - * @internal - * The method performs extensive validation and cleaning: - * 1. Validates errors is an array - * 2. For each error: validates required fields, cleans file paths and types, normalizes - * IssueType and SeverityLevel, parses line numbers, cleans descriptions and suggestions - * 3. Passes cleaned errors to callback - * - * @param input - Tool input containing errors array - * @returns String response indicating success or error details - * - * @throws Error if errors is not an array, required fields are missing, or validation fails - * - * @remarks - * - Empty errors array is valid and returns success message - * - File paths are cleaned to remove markdown, prefixes, and newlines - * - IssueType values are validated and normalized (fallback to CODE_ISSUE if invalid) - * - SeverityLevel values must be exactly one of: critical, high, medium, low - * - Line numbers are parsed from strings if needed (extracts first number found) - * - Descriptions and suggestions are cleaned but preserve newlines for readability - * - If multiple errors are concatenated in description, only first is extracted - * - * @example - * ```typescript - * const result = await tool.execute({ - * errors: [ - * { - * file: '**src/utils.ts**', - * line: '42', - * type: 'BUG', - * severity: 'HIGH', - * description: '**Null pointer** exception', - * suggestion: 'Add null check' - * } - * ] - * }); - * // Errors are cleaned: file='src/utils.ts', line=42, type='bug', severity='high' - * // Returns: "Successfully reported 1 error(s). Errors have been recorded for analysis." - * ``` - */ - execute(input: Record): Promise; -} diff --git a/build/github_action/src/agent/tools/builtin_tools/report_intent_tool.d.ts b/build/github_action/src/agent/tools/builtin_tools/report_intent_tool.d.ts deleted file mode 100644 index e36281bc..00000000 --- a/build/github_action/src/agent/tools/builtin_tools/report_intent_tool.d.ts +++ /dev/null @@ -1,137 +0,0 @@ -/** - * Report Intent Tool - Tool for reporting intent classification decision in structured format. - * - * This tool allows agents to report their intent classification decision, indicating whether - * the user prompt is an ORDER (should apply changes) or a QUESTION (should not apply changes). - * This is the primary way for agents to report their classification after analyzing the prompt. - * - * @internal - * This tool is used by the IntentClassifier agent to report classification decisions. The tool - * validates and cleans the reasoning text, ensuring it's plain text without markdown formatting, - * and validates the confidence level against the ConfidenceLevel enum. - * - * @remarks - * - shouldApplyChanges must be a boolean (true for orders, false for questions) - * - reasoning is cleaned to remove markdown formatting but preserves newlines - * - confidence must be one of: high, medium, low (from ConfidenceLevel enum) - * - This is the PRIMARY way to report intent classification - agents MUST use this tool - * - * @example - * ```typescript - * const tool = new ReportIntentTool({ - * onIntentReported: (shouldApply, reasoning, confidence) => { - * console.log('Intent:', shouldApply, confidence); - * } - * }); - * - * await tool.execute({ - * shouldApplyChanges: true, - * reasoning: 'User said "create a file" which is a clear order', - * confidence: 'high' - * }); - * ``` - */ -import { BaseTool } from '../base_tool'; -import { ConfidenceLevel } from '../../reasoning/intent_classifier/types'; -/** - * Options for configuring the ReportIntentTool. - * - * @internal - * The callback connects the tool to the intent reporting system, allowing classification - * decisions to be processed and stored. - * - * @property onIntentReported - Callback invoked with classification decision, reasoning, and confidence. - */ -export interface ReportIntentToolOptions { - /** - * Callback invoked when intent is reported. - * - * @internal - * This callback receives the classification decision (shouldApplyChanges), cleaned reasoning, - * and validated confidence level. The reasoning has been cleaned to remove markdown formatting. - * - * @param shouldApplyChanges - true if prompt is an order, false if it's a question - * @param reasoning - Cleaned reasoning text explaining the classification - * @param confidence - Confidence level (high, medium, or low) - */ - onIntentReported: (shouldApplyChanges: boolean, reasoning: string, confidence: ConfidenceLevel) => void; -} -/** - * ReportIntentTool - Tool for reporting intent classification decisions. - * - * This tool provides a structured interface for agents to report their intent classification - * decisions. It validates inputs, cleans reasoning text, and ensures confidence levels are valid. - * - * @internal - * The tool performs validation and cleaning: - * - Validates shouldApplyChanges is a boolean - * - Cleans reasoning to remove markdown formatting (preserves newlines) - * - Validates confidence level against ConfidenceLevel enum - * - Passes cleaned data to callback - */ -export declare class ReportIntentTool extends BaseTool { - private options; - /** - * Creates a new ReportIntentTool instance. - * - * @internal - * The options parameter provides the callback that receives the classification decision. - * - * @param options - Configuration object with callback for intent reporting - */ - constructor(options: ReportIntentToolOptions); - /** - * Returns the tool name used by the agent system. - * - * @internal - * This name is used when the agent calls the tool via tool calls. - * - * @returns Tool identifier: 'report_intent' - */ - getName(): string; - getDescription(): string; - getInputSchema(): { - type: 'object'; - properties: Record; - required: string[]; - additionalProperties?: boolean; - }; - /** - * Executes the tool with the provided input. - * - * This method validates and processes the intent classification decision, cleans the reasoning - * text, and passes the cleaned data to the callback. - * - * @internal - * The method performs the following steps: - * 1. Validates shouldApplyChanges is provided and converts to boolean - * 2. Validates reasoning is provided and is a string - * 3. Cleans reasoning to remove markdown formatting (preserves newlines) - * 4. Validates confidence is provided and is a valid ConfidenceLevel enum value - * 5. Passes cleaned data to callback - * - * @param input - Tool input containing shouldApplyChanges, reasoning, and confidence - * @returns String response indicating success - * - * @throws Error if required fields are missing, reasoning is empty after cleaning, or confidence is invalid - * - * @remarks - * - shouldApplyChanges is converted to boolean (handles truthy/falsy values) - * - Reasoning is cleaned to remove markdown but preserves newlines for readability - * - Confidence is normalized to lowercase and validated against ConfidenceLevel enum - * - Empty reasoning after cleaning throws an error - * - * @example - * ```typescript - * const result = await tool.execute({ - * shouldApplyChanges: true, - * reasoning: '**User said** "create a file" which is a clear order', - * confidence: 'HIGH' - * }); - * // Reasoning is cleaned: 'User said "create a file" which is a clear order' - * // Confidence is normalized: 'high' - * // Returns: "Successfully reported intent classification: shouldApplyChanges=true, confidence=high. Classification has been recorded." - * ``` - */ - execute(input: Record): Promise; -} diff --git a/build/github_action/src/agent/tools/builtin_tools/report_progress_tool.d.ts b/build/github_action/src/agent/tools/builtin_tools/report_progress_tool.d.ts deleted file mode 100644 index dfebf78c..00000000 --- a/build/github_action/src/agent/tools/builtin_tools/report_progress_tool.d.ts +++ /dev/null @@ -1,144 +0,0 @@ -/** - * Report Progress Tool - Tool for reporting task progress in structured format. - * - * This tool allows agents to report the progress percentage of a task based on code changes - * analysis. It reports the completion percentage (0-100) and a brief summary of the assessment. - * This is the primary way for agents to report progress after analyzing changes. - * - * @internal - * This tool is used by the ProgressDetector agent to report task completion percentage. The tool - * validates progress is within 0-100 range, cleans the summary text to remove markdown formatting, - * and rounds progress to integer for consistency. - * - * @remarks - * - progress must be a number between 0 and 100 (inclusive) - * - Progress can be provided as number or string (extracts number from string) - * - Progress is rounded to integer for consistency - * - summary is cleaned to remove markdown formatting but preserves newlines - * - This is the PRIMARY way to report progress - agents MUST use this tool - * - * @example - * ```typescript - * const tool = new ReportProgressTool({ - * onProgressReported: (progress, summary) => { - * console.log(`Progress: ${progress}%`); - * } - * }); - * - * await tool.execute({ - * progress: 75, - * summary: 'Most changes are complete, only tests remaining' - * }); - * ``` - */ -import { BaseTool } from '../base_tool'; -/** - * Options for configuring the ReportProgressTool. - * - * @internal - * The callback connects the tool to the progress reporting system, allowing progress - * assessments to be processed and stored. - * - * @property onProgressReported - Callback invoked with progress percentage and cleaned summary. - */ -export interface ReportProgressToolOptions { - /** - * Callback invoked when progress is reported. - * - * @internal - * This callback receives the progress percentage (0-100, rounded to integer) and cleaned - * summary text. The summary has been cleaned to remove markdown formatting. - * - * @param progress - Progress percentage (0-100, integer) - * @param summary - Cleaned summary text explaining the progress assessment - */ - onProgressReported: (progress: number, summary: string) => void; -} -/** - * ReportProgressTool - Tool for reporting task progress in structured format. - * - * This tool provides a structured interface for agents to report task completion percentage. - * It validates progress range, cleans summary text, and ensures data consistency. - * - * @internal - * The tool performs validation and cleaning: - * - Validates progress is within 0-100 range - * - Parses progress from string if needed (extracts first number) - * - Rounds progress to integer for consistency - * - Cleans summary to remove markdown formatting (preserves newlines) - * - Passes cleaned data to callback - */ -export declare class ReportProgressTool extends BaseTool { - private options; - /** - * Creates a new ReportProgressTool instance. - * - * @internal - * The options parameter provides the callback that receives the progress assessment. - * - * @param options - Configuration object with callback for progress reporting - */ - constructor(options: ReportProgressToolOptions); - /** - * Returns the tool name used by the agent system. - * - * @internal - * This name is used when the agent calls the tool via tool calls. - * - * @returns Tool identifier: 'report_progress' - */ - getName(): string; - getDescription(): string; - getInputSchema(): { - type: 'object'; - properties: Record; - required: string[]; - additionalProperties?: boolean; - }; - /** - * Executes the tool with the provided input. - * - * This method validates and processes the progress assessment, parses progress from number - * or string, validates the range, cleans the summary text, and passes the cleaned data - * to the callback. - * - * @internal - * The method performs the following steps: - * 1. Validates progress is provided - * 2. Parses progress from number or string (extracts first number from string) - * 3. Validates progress is within 0-100 range - * 4. Rounds progress to integer for consistency - * 5. Validates summary is provided and is a string - * 6. Cleans summary to remove markdown formatting (preserves newlines) - * 7. Passes cleaned data to callback - * - * @param input - Tool input containing progress and summary - * @returns String response indicating success - * - * @throws Error if progress is missing, invalid, or out of range; or if summary is missing or empty after cleaning - * - * @remarks - * - Progress can be provided as number or string (extracts first number from string) - * - Progress is rounded to integer for consistency (e.g., 75.5 becomes 76) - * - Summary is cleaned to remove markdown but preserves newlines for readability - * - Empty summary after cleaning throws an error - * - * @example - * ```typescript - * // With number - * const result = await tool.execute({ - * progress: 75, - * summary: '**Most changes** are complete' - * }); - * // Progress: 75, Summary: 'Most changes are complete' - * - * // With string - * const result2 = await tool.execute({ - * progress: '50%', - * summary: 'Halfway done' - * }); - * // Progress: 50, Summary: 'Halfway done' - * ``` - */ - execute(input: Record): Promise; -} diff --git a/build/github_action/src/agent/tools/builtin_tools/search_files_tool.d.ts b/build/github_action/src/agent/tools/builtin_tools/search_files_tool.d.ts deleted file mode 100644 index b926b64b..00000000 --- a/build/github_action/src/agent/tools/builtin_tools/search_files_tool.d.ts +++ /dev/null @@ -1,157 +0,0 @@ -/** - * Search Files Tool - Searches for files by name or content. - * - * This tool allows agents to search for files in the repository by name, path, or content - * keywords. It returns a list of matching file paths, with optional result limiting for - * efficiency. - * - * @internal - * This tool is used by agents to find files during their reasoning process. It delegates - * the actual search logic to the searchFiles callback, which can implement various search - * strategies (name matching, path patterns, content search, etc.). - * - * @remarks - * - query is required and can be a file name, path pattern, or content keyword - * - max_results defaults to 1000 but can be set higher (>= 10000 returns all results) - * - Results are formatted as a numbered list for easy reading - * - Returns empty message if no files match the query - * - * @example - * ```typescript - * const tool = new SearchFilesTool({ - * searchFiles: (query) => { - * // Implement search logic - * return ['src/utils.ts', 'src/helper.ts']; - * } - * }); - * - * // Search with default limit - * await tool.execute({ query: 'utils' }); - * - * // Search with custom limit - * await tool.execute({ query: 'test', max_results: 5000 }); - * ``` - */ -import { BaseTool } from '../base_tool'; -/** - * Options for configuring the SearchFilesTool. - * - * @internal - * These callbacks connect the tool to the file search system, allowing various search - * strategies to be implemented. - * - * @property searchFiles - Callback to perform file search. Returns array of matching file paths. - * @property getAllFiles - Optional callback to get all files (for comprehensive searches). - */ -export interface SearchFilesToolOptions { - /** - * Performs file search based on query. - * - * @internal - * This callback implements the actual search logic. It can search by file name, path - * pattern, content keywords, or any combination. The implementation is flexible and - * can use various search strategies. - * - * @param query - Search query (file name, path pattern, or content keyword) - * @returns Array of matching file paths - */ - searchFiles: (query: string) => string[]; - /** - * Optional callback to get all files. - * - * @internal - * This callback can be used for comprehensive searches when max_results is very high - * (>= 10000). It returns all files in the repository. - * - * @returns Array of all file paths - */ - getAllFiles?: () => string[]; -} -/** - * SearchFilesTool - Tool for searching files by name or content. - * - * This tool provides a unified interface for file searching, with result limiting and - * formatting capabilities. - * - * @internal - * The tool validates the query, delegates search to the callback, limits results if needed, - * and formats the response as a numbered list. For very large max_results (>= 10000), it - * returns all results without limiting. - */ -export declare class SearchFilesTool extends BaseTool { - private options; - /** - * Creates a new SearchFilesTool instance. - * - * @internal - * The options parameter provides callbacks that implement the search logic. - * - * @param options - Configuration object with callbacks for file search - */ - constructor(options: SearchFilesToolOptions); - /** - * Returns the tool name used by the agent system. - * - * @internal - * This name is used when the agent calls the tool via tool calls. - * - * @returns Tool identifier: 'search_files' - */ - getName(): string; - /** - * Returns the tool description shown to the agent. - * - * @internal - * This description helps the agent understand when and how to use this tool. - * It's included in the agent's available tools list. - * - * @returns Human-readable description of the tool's purpose - */ - getDescription(): string; - getInputSchema(): { - type: 'object'; - properties: Record; - required: string[]; - additionalProperties?: boolean; - }; - /** - * Executes the tool with the provided input. - * - * This method performs a file search based on the query, limits results if needed, and - * formats the response as a numbered list. - * - * @internal - * The method performs the following steps: - * 1. Validates query is provided and is a string - * 2. Validates max_results is at least 1 - * 3. Delegates search to searchFiles callback - * 4. Limits results if max_results is reasonable (< 10000) - * 5. Formats results as numbered list or returns empty message - * - * @param input - Tool input containing query and optional max_results - * @returns Formatted string with numbered list of matching files, or empty message if none found - * - * @throws Error if query is missing or not a string, or if max_results is less than 1 - * - * @remarks - * - max_results defaults to 1000 for comprehensive searches - * - For max_results >= 10000, all results are returned (no limiting) - * - Results are formatted as a numbered list for easy reading - * - Returns empty message (not exception) if no files match - * - * @example - * ```typescript - * // Search with default limit - * const result = await tool.execute({ query: 'utils' }); - * // Returns: "Found 2 file(s) matching "utils":\n\n1. src/utils.ts\n2. src/utils/helper.ts" - * - * // Search with custom limit - * const result2 = await tool.execute({ query: 'test', max_results: 5000 }); - * - * // No results - * const result3 = await tool.execute({ query: 'nonexistent' }); - * // Returns: "No files found matching query: "nonexistent"" - * ``` - */ - execute(input: Record): Promise; -} diff --git a/build/github_action/src/agent/tools/index.d.ts b/build/github_action/src/agent/tools/index.d.ts deleted file mode 100644 index edc66997..00000000 --- a/build/github_action/src/agent/tools/index.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -/** - * Export all tool-related classes - */ -export * from './base_tool'; -export * from './tool_registry'; -export * from './tool_executor'; diff --git a/build/github_action/src/agent/tools/tool_executor.d.ts b/build/github_action/src/agent/tools/tool_executor.d.ts deleted file mode 100644 index 8bf3da83..00000000 --- a/build/github_action/src/agent/tools/tool_executor.d.ts +++ /dev/null @@ -1,34 +0,0 @@ -/** - * Tool Executor for Agent SDK - * Executes tool calls and returns results - */ -import { ToolRegistry } from './tool_registry'; -import { ToolCall, ToolResult } from '../types'; -export declare class ToolExecutor { - private registry; - constructor(registry: ToolRegistry); - /** - * Execute a single tool call - */ - execute(toolCall: ToolCall): Promise; - /** - * Execute multiple tool calls in parallel - */ - executeAll(toolCalls: ToolCall[]): Promise; - /** - * Execute multiple tool calls sequentially - */ - executeAllSequential(toolCalls: ToolCall[]): Promise; - /** - * Check if tool is available - */ - isToolAvailable(name: string): boolean; - /** - * Get available tool names - */ - getAvailableTools(): string[]; - /** - * Get all tool definitions - */ - getToolDefinitions(): import("../types").ToolDefinition[]; -} diff --git a/build/github_action/src/agent/tools/tool_registry.d.ts b/build/github_action/src/agent/tools/tool_registry.d.ts deleted file mode 100644 index 2baff479..00000000 --- a/build/github_action/src/agent/tools/tool_registry.d.ts +++ /dev/null @@ -1,40 +0,0 @@ -/** - * Tool Registry for managing available tools - */ -import { BaseTool } from './base_tool'; -import { ToolDefinition } from '../types'; -export declare class ToolRegistry { - private tools; - /** - * Register a tool - */ - register(tool: BaseTool): void; - /** - * Register multiple tools - */ - registerAll(tools: BaseTool[]): void; - /** - * Get tool by name - */ - get(name: string): BaseTool | undefined; - /** - * Check if tool exists - */ - has(name: string): boolean; - /** - * Get all tool definitions - */ - getAllDefinitions(): ToolDefinition[]; - /** - * Get all registered tool names - */ - getToolNames(): string[]; - /** - * Clear all tools - */ - clear(): void; - /** - * Get tool count - */ - getCount(): number; -} diff --git a/build/github_action/src/agent/types/agent_types.d.ts b/build/github_action/src/agent/types/agent_types.d.ts deleted file mode 100644 index 00614670..00000000 --- a/build/github_action/src/agent/types/agent_types.d.ts +++ /dev/null @@ -1,99 +0,0 @@ -/** - * Agent types for the Agent SDK - */ -import { Message } from './message_types'; -import { ToolCall, ToolResult } from './tool_types'; -export type ToolPermissionStrategy = 'allowlist' | 'blocklist' | 'all'; -export type StreamChunk = { - type: 'text' | 'tool_call' | 'reasoning' | 'done'; - content: string; - toolCall?: ToolCall; -}; -export interface ToolPermissions { - strategy: ToolPermissionStrategy; - allowed?: string[]; - blocked?: string[]; -} -export interface BudgetConfig { - maxCost?: number; - maxTokens?: number; - warnAtPercent?: number; -} -export interface TimeoutConfig { - apiCall?: number; - toolExecution?: number; - totalSession?: number; -} -export interface RetryConfig { - maxRetries?: number; - initialDelay?: number; - maxDelay?: number; - backoffMultiplier?: number; - retryableErrors?: number[]; -} -export interface AgentOptions { - model: string; - /** OpenCode server URL (e.g. http://localhost:4096) */ - serverUrl: string; - systemPrompt?: string; - maxTurns?: number; - maxTokens?: number; - temperature?: number; - tools?: any[]; - onTurnComplete?: (turn: TurnResult) => void; - onError?: (error: Error) => void; - onToolCall?: (toolCall: ToolCall) => void; - onToolResult?: (result: ToolResult) => void; - streaming?: boolean; - onStreamChunk?: (chunk: StreamChunk) => void; - toolPermissions?: ToolPermissions; - maxContextLength?: number; - contextCompressionEnabled?: boolean; - sessionId?: string; - persistSession?: boolean; - trackMetrics?: boolean; - onMetrics?: (metrics: Metrics) => void; - budget?: BudgetConfig; - timeouts?: TimeoutConfig; - retry?: RetryConfig; -} -export interface TurnResult { - turnNumber: number; - assistantMessage: string; - toolCalls: ToolCall[]; - toolResults?: ToolResult[]; - reasoning?: string; - timestamp: number; -} -export interface Metrics { - totalTokens: { - input: number; - output: number; - }; - totalCost?: number; - apiCalls: number; - toolCalls: number; - averageLatency: number; - totalDuration: number; - errors: number; -} -export interface AgentResult { - finalResponse: string; - turns: TurnResult[]; - toolCalls: ToolCall[]; - messages: Message[]; - totalTokens?: { - input: number; - output: number; - }; - metrics?: Metrics; - error?: Error; - truncated?: boolean; - budgetExceeded?: boolean; - timeoutExceeded?: boolean; -} -export interface ParsedResponse { - text: string; - toolCalls?: ToolCall[]; - reasoning?: string; -} diff --git a/build/github_action/src/agent/types/index.d.ts b/build/github_action/src/agent/types/index.d.ts deleted file mode 100644 index dc2183fb..00000000 --- a/build/github_action/src/agent/types/index.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -/** - * Export all types - */ -export * from './message_types'; -export * from './tool_types'; -export * from './agent_types'; diff --git a/build/github_action/src/agent/types/message_types.d.ts b/build/github_action/src/agent/types/message_types.d.ts deleted file mode 100644 index b563a623..00000000 --- a/build/github_action/src/agent/types/message_types.d.ts +++ /dev/null @@ -1,38 +0,0 @@ -/** - * Message types for the Agent SDK - * Compatible with Anthropic Messages API format - */ -export type MessageRole = 'system' | 'user' | 'assistant'; -export interface TextContent { - type: 'text'; - text: string; -} -export interface ToolUseContent { - type: 'tool_use'; - id: string; - name: string; - input: Record; -} -export interface ToolResultContent { - type: 'tool_result'; - tool_use_id: string; - content: string | any; - is_error?: boolean; -} -export type ContentBlock = TextContent | ToolUseContent | ToolResultContent; -export interface Message { - role: MessageRole; - content: string | ContentBlock[]; -} -export interface SystemMessage extends Message { - role: 'system'; - content: string; -} -export interface UserMessage extends Message { - role: 'user'; - content: string | ContentBlock[]; -} -export interface AssistantMessage extends Message { - role: 'assistant'; - content: ContentBlock[]; -} diff --git a/build/github_action/src/agent/types/response_schema.d.ts b/build/github_action/src/agent/types/response_schema.d.ts deleted file mode 100644 index df1396be..00000000 --- a/build/github_action/src/agent/types/response_schema.d.ts +++ /dev/null @@ -1,39 +0,0 @@ -/** - * JSON Schema for Agent responses - * Used with OpenCode JSON mode - */ -export declare const AGENT_RESPONSE_SCHEMA: { - type: string; - properties: { - response: { - type: string; - description: string; - }; - tool_calls: { - type: string; - description: string; - items: { - type: string; - properties: { - id: { - type: string; - description: string; - }; - name: { - type: string; - description: string; - }; - input: { - type: string; - description: string; - additionalProperties: boolean; - }; - }; - required: string[]; - additionalProperties: boolean; - }; - }; - }; - required: string[]; - additionalProperties: boolean; -}; diff --git a/build/github_action/src/agent/types/tool_types.d.ts b/build/github_action/src/agent/types/tool_types.d.ts deleted file mode 100644 index 08267463..00000000 --- a/build/github_action/src/agent/types/tool_types.d.ts +++ /dev/null @@ -1,29 +0,0 @@ -/** - * Tool types for the Agent SDK - */ -export interface ToolDefinition { - name: string; - description: string; - inputSchema: { - type: 'object'; - properties: Record; - required: string[]; - additionalProperties?: boolean; - }; -} -export interface ToolCall { - id: string; - name: string; - input: Record; -} -export interface ToolResult { - toolCallId: string; - content: string | any; - isError?: boolean; - errorMessage?: string; -} -export interface ToolExecutionResult { - success: boolean; - result: any; - error?: string; -} diff --git a/build/github_action/src/agent/utils/error_handler.d.ts b/build/github_action/src/agent/utils/error_handler.d.ts deleted file mode 100644 index 3807bc06..00000000 --- a/build/github_action/src/agent/utils/error_handler.d.ts +++ /dev/null @@ -1,32 +0,0 @@ -/** - * Error handler for Agent SDK - */ -export declare class AgentError extends Error { - code: string; - context?: any | undefined; - constructor(message: string, code: string, context?: any | undefined); -} -export declare class ToolExecutionError extends AgentError { - toolName: string; - toolInput?: any | undefined; - constructor(message: string, toolName: string, toolInput?: any | undefined); -} -export declare class APIError extends AgentError { - statusCode?: number | undefined; - response?: any | undefined; - constructor(message: string, statusCode?: number | undefined, response?: any | undefined); -} -export declare class ValidationError extends AgentError { - field?: string | undefined; - constructor(message: string, field?: string | undefined); -} -export declare class ErrorHandler { - /** - * Handle and format errors - */ - static handle(error: unknown): Error; - /** - * Check if error is retryable - */ - static isRetryable(error: Error): boolean; -} diff --git a/build/github_action/src/agent/utils/index.d.ts b/build/github_action/src/agent/utils/index.d.ts deleted file mode 100644 index ef432e8d..00000000 --- a/build/github_action/src/agent/utils/index.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -/** - * Export all utilities - */ -export * from './response_parser'; -export * from './prompt_builder'; -export * from './error_handler'; diff --git a/build/github_action/src/agent/utils/prompt_builder.d.ts b/build/github_action/src/agent/utils/prompt_builder.d.ts deleted file mode 100644 index c7ec643a..00000000 --- a/build/github_action/src/agent/utils/prompt_builder.d.ts +++ /dev/null @@ -1,25 +0,0 @@ -/** - * Prompt builder for Agent SDK - * Builds prompts that include tool definitions and conversation history - */ -import { Message } from '../types'; -import { ToolDefinition } from '../types'; -export declare class PromptBuilder { - /** - * Build a complete prompt from messages and tools - * This converts the message history into a format suitable for OpenCode - */ - static buildPrompt(messages: Message[], tools?: ToolDefinition[]): string; - /** - * Build tools section for prompt (simplified to save tokens) - */ - private static buildToolsSection; - /** - * Format a message for the prompt - */ - private static formatMessage; - /** - * Get response schema for JSON mode - */ - private static getResponseSchema; -} diff --git a/build/github_action/src/agent/utils/response_parser.d.ts b/build/github_action/src/agent/utils/response_parser.d.ts deleted file mode 100644 index 280b54c4..00000000 --- a/build/github_action/src/agent/utils/response_parser.d.ts +++ /dev/null @@ -1,30 +0,0 @@ -/** - * Response parser for OpenCode JSON responses - */ -import { ParsedResponse } from '../types'; -export declare class ResponseParser { - /** - * Parse JSON response from OpenCode - * Expected format: - * { - * "reasoning": "...", - * "response": "...", - * "tool_calls": [ - * { - * "id": "call_1", - * "name": "read_file", - * "input": { "file_path": "..." } - * } - * ] - * } - */ - static parse(jsonResponse: any): ParsedResponse; - /** - * Generate a unique tool call ID - */ - private static generateToolCallId; - /** - * Validate parsed response - */ - static validate(parsed: ParsedResponse): boolean; -} diff --git a/build/github_action/src/agent_tester.d.ts b/build/github_action/src/agent_tester.d.ts deleted file mode 100644 index b7988016..00000000 --- a/build/github_action/src/agent_tester.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -#!/usr/bin/env node -export {}; diff --git a/build/github_action/src/agent_tester_commands.d.ts b/build/github_action/src/agent_tester_commands.d.ts deleted file mode 100644 index e21da60b..00000000 --- a/build/github_action/src/agent_tester_commands.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/env node -/** - * Agent SDK Test Commands - * All testing commands for the Agent SDK - */ -import { Command } from 'commander'; -/** - * Register all agent test commands to the provided program - */ -export declare function registerAgentTestCommands(program: Command): void; diff --git a/build/github_action/src/data/graph/add_project_item_response.d.ts b/build/github_action/src/data/graph/add_project_item_response.d.ts deleted file mode 100644 index 7eb188fb..00000000 --- a/build/github_action/src/data/graph/add_project_item_response.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -export interface AddProjectItemResponse { - addProjectV2ItemById: { - item: { - id: string; - }; - }; -} diff --git a/build/github_action/src/data/graph/ai_responses.d.ts b/build/github_action/src/data/graph/ai_responses.d.ts deleted file mode 100644 index 5c1e9a7b..00000000 --- a/build/github_action/src/data/graph/ai_responses.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -export interface PatchSummary { - filePath: string; - summary: string; - changes: string[]; -} diff --git a/build/github_action/src/data/model/ai_response.d.ts b/build/github_action/src/data/model/ai_response.d.ts deleted file mode 100644 index 0135b4d4..00000000 --- a/build/github_action/src/data/model/ai_response.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -export interface AiResponse { - text_response: string; - action: 'none' | 'analyze_files'; - related_files: string[]; - complete: boolean; -} diff --git a/build/github_action/src/data/model/ai_response_schema.d.ts b/build/github_action/src/data/model/ai_response_schema.d.ts deleted file mode 100644 index 54adfc1c..00000000 --- a/build/github_action/src/data/model/ai_response_schema.d.ts +++ /dev/null @@ -1,31 +0,0 @@ -/** - * JSON Schema for AiResponse interface - * This schema is used to enforce structured JSON responses from the AI - */ -export declare const AI_RESPONSE_JSON_SCHEMA: { - type: string; - properties: { - text_response: { - type: string; - description: string; - }; - action: { - type: string; - enum: string[]; - description: string; - }; - related_files: { - type: string; - items: { - type: string; - }; - description: string; - }; - complete: { - type: string; - description: string; - }; - }; - required: string[]; - additionalProperties: boolean; -}; diff --git a/build/github_action/src/data/model/codebase_analysis_schema.d.ts b/build/github_action/src/data/model/codebase_analysis_schema.d.ts deleted file mode 100644 index b2bb7f82..00000000 --- a/build/github_action/src/data/model/codebase_analysis_schema.d.ts +++ /dev/null @@ -1,30 +0,0 @@ -/** - * JSON Schema for codebase analysis responses - * Used in Step 0 of the thinking process to analyze codebase structure - */ -export declare const CODEBASE_ANALYSIS_JSON_SCHEMA: { - type: string; - description: string; - items: { - type: string; - properties: { - path: { - type: string; - description: string; - }; - description: { - type: string; - description: string; - }; - relationships: { - type: string; - description: string; - items: { - type: string; - }; - }; - }; - required: string[]; - additionalProperties: boolean; - }; -}; diff --git a/build/github_action/src/data/model/supabase_config.d.ts b/build/github_action/src/data/model/supabase_config.d.ts deleted file mode 100644 index 3ac8c9fe..00000000 --- a/build/github_action/src/data/model/supabase_config.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -export declare class SupabaseConfig { - private url; - private key; - constructor(url: string, key: string); - getUrl(): string; - getKey(): string; -} diff --git a/build/github_action/src/data/model/think_response.d.ts b/build/github_action/src/data/model/think_response.d.ts deleted file mode 100644 index 1a5e0941..00000000 --- a/build/github_action/src/data/model/think_response.d.ts +++ /dev/null @@ -1,82 +0,0 @@ -/** - * Status levels for TODO items - */ -export declare enum TodoStatus { - PENDING = "pending", - IN_PROGRESS = "in_progress", - COMPLETED = "completed", - CANCELLED = "cancelled" -} -/** - * Actions for managing TODOs - */ -export declare enum TodoAction { - CREATE = "create", - UPDATE = "update", - LIST = "list" -} -/** - * Types of changes that can be proposed to files - */ -export declare enum ChangeType { - CREATE = "create", - MODIFY = "modify", - DELETE = "delete", - REFACTOR = "refactor" -} -export interface FileAnalysis { - path: string; - key_findings: string; - relevance: 'high' | 'medium' | 'low'; -} -export interface ProposedChange { - file_path: string; - change_type: ChangeType; - description: string; - suggested_code?: string; - reasoning: string; -} -export interface ThinkResponse { - reasoning: string; - action: 'search_files' | 'read_file' | 'analyze_code' | 'propose_changes' | 'complete' | 'update_todos'; - files_to_search?: string[]; - files_to_read?: string[]; - analyzed_files?: FileAnalysis[]; - proposed_changes?: ProposedChange[]; - todo_updates?: { - create?: Array<{ - content: string; - status?: TodoStatus; - }>; - update?: Array<{ - id: string; - status?: TodoStatus; - notes?: string; - }>; - }; - complete: boolean; - final_analysis?: string; -} -export interface ThinkStep { - step_number: number; - action: string; - reasoning: string; - files_involved?: string[]; - findings?: string; - timestamp: number; -} -export interface ThinkTodoItem { - id: string; - content: string; - status: TodoStatus; - created_at: number; - updated_at: number; - completed_at?: number; - related_files?: string[]; - related_changes?: string[]; - notes?: string; -} -export interface ThinkTodoList { - items: ThinkTodoItem[]; - last_updated: number; -} diff --git a/build/github_action/src/data/model/think_response_schema.d.ts b/build/github_action/src/data/model/think_response_schema.d.ts deleted file mode 100644 index c86c7e38..00000000 --- a/build/github_action/src/data/model/think_response_schema.d.ts +++ /dev/null @@ -1,137 +0,0 @@ -/** - * JSON Schema for ThinkResponse interface - * This schema is used for structured AI reasoning and analysis responses - */ -export declare const THINK_RESPONSE_JSON_SCHEMA: { - type: string; - properties: { - reasoning: { - type: string; - description: string; - }; - action: { - type: string; - enum: string[]; - description: string; - }; - files_to_search: { - type: string; - items: { - type: string; - }; - description: string; - }; - files_to_read: { - type: string; - items: { - type: string; - }; - description: string; - }; - analyzed_files: { - type: string; - items: { - type: string; - properties: { - path: { - type: string; - }; - key_findings: { - type: string; - }; - relevance: { - type: string; - enum: string[]; - }; - }; - required: string[]; - additionalProperties: boolean; - }; - description: string; - }; - proposed_changes: { - type: string; - items: { - type: string; - properties: { - file_path: { - type: string; - }; - change_type: { - type: string; - enum: string[]; - }; - description: { - type: string; - }; - suggested_code: { - type: string; - }; - reasoning: { - type: string; - }; - }; - required: string[]; - additionalProperties: boolean; - }; - description: string; - }; - complete: { - type: string; - description: string; - }; - final_analysis: { - type: string; - description: string; - }; - todo_updates: { - type: string; - description: string; - properties: { - create: { - type: string; - items: { - type: string; - properties: { - content: { - type: string; - }; - status: { - type: string; - enum: string[]; - }; - }; - required: string[]; - additionalProperties: boolean; - }; - description: string; - }; - update: { - type: string; - items: { - type: string; - properties: { - id: { - type: string; - }; - status: { - type: string; - enum: string[]; - }; - notes: { - type: string; - }; - }; - required: string[]; - additionalProperties: boolean; - }; - description: string; - }; - }; - required: string[]; - additionalProperties: boolean; - }; - }; - required: string[]; - additionalProperties: boolean; -}; diff --git a/build/github_action/src/data/repository/branch_repository.d.ts b/build/github_action/src/data/repository/branch_repository.d.ts index f65ea00a..e8965846 100644 --- a/build/github_action/src/data/repository/branch_repository.d.ts +++ b/build/github_action/src/data/repository/branch_repository.d.ts @@ -33,7 +33,7 @@ export declare class BranchRepository { totalCommits: number; files: { filename: string; - status: "added" | "removed" | "modified" | "renamed" | "copied" | "changed" | "unchanged"; + status: "modified" | "added" | "removed" | "renamed" | "copied" | "changed" | "unchanged"; additions: number; deletions: number; changes: number; diff --git a/build/github_action/src/data/repository/supabase_repository.d.ts b/build/github_action/src/data/repository/supabase_repository.d.ts deleted file mode 100644 index f1a9ecc2..00000000 --- a/build/github_action/src/data/repository/supabase_repository.d.ts +++ /dev/null @@ -1,98 +0,0 @@ -import { SupabaseConfig } from '../model/supabase_config'; -export interface AICachedFileInfo { - owner: string; - repository: string; - branch: string; - file_name: string; - path: string; - sha: string; - description: string; - consumes: string[]; - consumed_by: string[]; - error_counter_total?: number; - error_counter_critical?: number; - error_counter_high?: number; - error_counter_medium?: number; - error_counter_low?: number; - error_types?: string[]; - errors_payload?: string; - created_at?: string; - last_updated?: string; -} -export declare class SupabaseRepository { - private readonly AI_FILE_CACHE_TABLE; - private readonly MAX_BATCH_SIZE; - private readonly DEFAULT_TIMEOUT; - private supabase; - constructor(config: SupabaseConfig); - /** - * Set or update AI file cache entry - * If SHA hasn't changed, this will update the entry - */ - setAIFileCache: (owner: string, repository: string, branch: string, fileInfo: { - file_name: string; - path: string; - sha: string; - description: string; - consumes: string[]; - consumed_by: string[]; - error_counter_total?: number; - error_counter_critical?: number; - error_counter_high?: number; - error_counter_medium?: number; - error_counter_low?: number; - error_types?: string[]; - errors_payload?: string; - }) => Promise; - /** - * Get AI file cache entry by path - */ - getAIFileCache: (owner: string, repository: string, branch: string, filePath: string) => Promise; - /** - * Get all AI file cache entries for a branch - */ - getAIFileCachesByBranch: (owner: string, repository: string, branch: string) => Promise; - /** - * Remove AI file cache entry by path - */ - removeAIFileCacheByPath: (owner: string, repository: string, branch: string, filePath: string) => Promise; - /** - * Duplicate AI file cache entries from one branch to another - */ - duplicateAIFileCacheByBranch: (owner: string, repository: string, sourceBranch: string, targetBranch: string) => Promise; - /** - * Remove all AI file cache entries for a branch - */ - removeAIFileCacheByBranch: (owner: string, repository: string, branch: string) => Promise; - /** - * Get SHA by path (for checking if file is cached) - */ - getShasumByPath: (owner: string, repository: string, branch: string, path: string) => Promise; - /** - * Get distinct paths for a branch - */ - getDistinctPaths: (owner: string, repository: string, branch: string) => Promise; - /** - * Get distinct branches for an owner/repository - */ - getDistinctBranches: (owner: string, repository: string) => Promise; - /** - * Get AI file cache entry by SHA (searches across all branches for the same owner/repository) - * Returns the first match found, which can be used to reuse descriptions - */ - getAIFileCacheBySha: (owner: string, repository: string, sha: string) => Promise; - /** - * Verify that a table exists in Supabase - */ - verifyTableExists: (tableName: string) => Promise<{ - exists: boolean; - error?: string; - }>; - /** - * Verify that an RPC function exists in Supabase - */ - verifyRpcFunctionExists: (functionName: string, testParams: any) => Promise<{ - exists: boolean; - error?: string; - }>; -} diff --git a/build/github_action/src/mcp_tester_commands.d.ts b/build/github_action/src/mcp_tester_commands.d.ts deleted file mode 100644 index 07c2ea4b..00000000 --- a/build/github_action/src/mcp_tester_commands.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -/** - * MCP Tester Commands - * CLI commands for testing MCP functionality - */ -import { Command } from 'commander'; -export declare function registerMCPTestCommands(program: Command): void; diff --git a/build/github_action/src/sub_agent_tester_commands.d.ts b/build/github_action/src/sub_agent_tester_commands.d.ts deleted file mode 100644 index b61c8cd4..00000000 --- a/build/github_action/src/sub_agent_tester_commands.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -/** - * SubAgent Tester Commands - * CLI commands for testing SubAgent functionality - */ -import { Command } from 'commander'; -export declare function registerSubAgentTestCommands(program: Command): void; diff --git a/build/github_action/src/tec_tester_commands.d.ts b/build/github_action/src/tec_tester_commands.d.ts deleted file mode 100644 index a223fa69..00000000 --- a/build/github_action/src/tec_tester_commands.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -/** - * TEC (TypeScript Error Checker) Tester Commands - * CLI commands for testing error detection system - */ -import { Command } from 'commander'; -export declare function registerTECTestCommands(program: Command): void; diff --git a/build/github_action/src/usecase/actions/__tests__/create_release_use_case.test.d.ts b/build/github_action/src/usecase/actions/__tests__/create_release_use_case.test.d.ts new file mode 100644 index 00000000..cb0ff5c3 --- /dev/null +++ b/build/github_action/src/usecase/actions/__tests__/create_release_use_case.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/github_action/src/usecase/actions/__tests__/create_tag_use_case.test.d.ts b/build/github_action/src/usecase/actions/__tests__/create_tag_use_case.test.d.ts new file mode 100644 index 00000000..cb0ff5c3 --- /dev/null +++ b/build/github_action/src/usecase/actions/__tests__/create_tag_use_case.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/github_action/src/usecase/actions/__tests__/initial_setup_use_case.test.d.ts b/build/github_action/src/usecase/actions/__tests__/initial_setup_use_case.test.d.ts new file mode 100644 index 00000000..cb0ff5c3 --- /dev/null +++ b/build/github_action/src/usecase/actions/__tests__/initial_setup_use_case.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/github_action/src/usecase/actions/__tests__/publish_github_action_use_case.test.d.ts b/build/github_action/src/usecase/actions/__tests__/publish_github_action_use_case.test.d.ts new file mode 100644 index 00000000..cb0ff5c3 --- /dev/null +++ b/build/github_action/src/usecase/actions/__tests__/publish_github_action_use_case.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/github_action/src/usecase/actions/__tests__/recommend_steps_use_case.test.d.ts b/build/github_action/src/usecase/actions/__tests__/recommend_steps_use_case.test.d.ts new file mode 100644 index 00000000..cb0ff5c3 --- /dev/null +++ b/build/github_action/src/usecase/actions/__tests__/recommend_steps_use_case.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/github_action/src/usecase/actions/__tests__/vector_action_use_case.test.d.ts b/build/github_action/src/usecase/actions/__tests__/vector_action_use_case.test.d.ts deleted file mode 100644 index 69d0ee60..00000000 --- a/build/github_action/src/usecase/actions/__tests__/vector_action_use_case.test.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Tests for VectorActionUseCase - Orphaned Branch Detection - */ -export {}; diff --git a/build/github_action/src/usecase/actions/detect_errors_use_case.d.ts b/build/github_action/src/usecase/actions/detect_errors_use_case.d.ts deleted file mode 100644 index aa3d8582..00000000 --- a/build/github_action/src/usecase/actions/detect_errors_use_case.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Execution } from '../../data/model/execution'; -import { Result } from '../../data/model/result'; -import { ParamUseCase } from '../base/param_usecase'; -export declare class DetectErrorsUseCase implements ParamUseCase { - taskId: string; - private issueRepository; - private branchRepository; - private aiRepository; - invoke(param: Execution): Promise; -} diff --git a/build/github_action/src/usecase/actions/vector_action_removal_use_case.d.ts b/build/github_action/src/usecase/actions/vector_action_removal_use_case.d.ts deleted file mode 100644 index 38e75fbe..00000000 --- a/build/github_action/src/usecase/actions/vector_action_removal_use_case.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Execution } from '../../data/model/execution'; -import { Result } from '../../data/model/result'; -import { ParamUseCase } from '../base/param_usecase'; -export declare class VectorActionRemovalUseCase implements ParamUseCase { - taskId: string; - invoke(param: Execution): Promise; - private removeAICacheByBranch; -} diff --git a/build/github_action/src/usecase/actions/vector_action_use_case.d.ts b/build/github_action/src/usecase/actions/vector_action_use_case.d.ts deleted file mode 100644 index 7b80611f..00000000 --- a/build/github_action/src/usecase/actions/vector_action_use_case.d.ts +++ /dev/null @@ -1,176 +0,0 @@ -import { Execution } from '../../data/model/execution'; -import { Result } from '../../data/model/result'; -import { ParamUseCase } from '../base/param_usecase'; -/** - * VectorActionUseCase - Processes repository files and creates AI cache in Supabase. - * - * This use case is responsible for: - * - Processing files from GitHub repositories and generating AI descriptions - * - Caching file metadata (descriptions, imports, error information) in Supabase - * - Detecting and removing orphaned branches from the cache - * - Reusing cached data across branches when files have the same SHA - * - * @internal - * This class is used internally by the SingleActionUseCase when the AI cache action is triggered. - * It processes files sequentially per branch and maintains a cache of file metadata for efficient - * codebase analysis and search operations. - */ -export declare class VectorActionUseCase implements ParamUseCase { - taskId: string; - private fileRepository; - private branchRepository; - private aiRepository; - private fileImportAnalyzer; - private fileCacheManager; - private codebaseAnalyzer; - constructor(); - /** - * Main entry point for the VectorActionUseCase. - * - * Processes repository files and creates/updates AI cache in Supabase. The process includes: - * 1. Validating configuration (Supabase, AI) - * 2. Determining which branches to process (specific branch or all branches) - * 3. Processing each branch: analyzing files, generating descriptions, detecting errors - * 4. Cleaning up orphaned branches (branches that no longer exist in GitHub) - * - * @internal - * This method orchestrates the entire cache building process. It handles errors gracefully - * and continues processing even if individual branches fail. - * - * @param param - Execution parameters containing repository info, tokens, AI config, and Supabase config - * @returns Array of Result objects indicating success/failure of each operation - * - * @remarks - * - If no specific branch is provided via `param.commit.branch`, all branches are processed - * - Orphaned branch detection runs after processing all branches to ensure accurate comparison - * - Each branch is processed independently; failures in one branch don't stop processing of others - * - * @example - * ```typescript - * const useCase = new VectorActionUseCase(); - * const results = await useCase.invoke(execution); - * // Results contain information about processed files, reused cache, and orphaned branches - * ``` - */ - invoke(param: Execution): Promise; - /** - * Processes and caches files for a specific branch. - * - * This method handles the complete file processing pipeline for a single branch: - * 1. Retrieves all files from the repository for the given branch - * 2. Builds relationship maps (imports/exports) for all files - * 3. For each file: - * - Calculates SHA to check if file has changed - * - Skips if SHA matches existing cache (optimization) - * - Reuses description/errors if SHA exists in another branch - * - Generates new AI description if file is new or changed - * - Detects errors using ErrorDetector - * - Saves metadata to Supabase - * 4. Removes files from cache that no longer exist in the repository - * - * @internal - * This is a private method called by invoke() for each branch. It's designed to be - * idempotent - running it multiple times on the same branch is safe and efficient. - * - * @param param - Execution parameters - * @param branch - Branch name to process - * @param branchIndex - Current branch index (for progress logging) - * @param totalBranches - Total number of branches being processed (for progress logging) - * - * @returns Object containing: - * - results: Array of Result objects for this branch - * - filesProcessed: Number of files successfully processed and saved - * - filesReused: Number of files that reused cache from other branches - * - filesSkipped: Number of files skipped (unchanged, same SHA) - * - filesGenerated: Number of files that required new AI description generation - * - filesRemoved: Number of files removed from cache (no longer in repository) - * - success: Whether the branch processing completed successfully - * - * @remarks - * - File processing is optimized: files with unchanged SHA are skipped entirely - * - SHA-based reuse allows sharing descriptions across branches for identical files - * - Error detection is optional and failures don't block file caching - * - The cleanup phase (removing deleted files) runs after processing all files - * - * @example - * ```typescript - * const result = await prepareCacheOnBranch(execution, 'develop', 1, 3); - * // result.filesProcessed = 150, result.filesReused = 50, result.filesSkipped = 200 - * ``` - */ - private prepareCacheOnBranch; - /** - * Removes orphaned branches from Supabase AI cache. - * - * An orphaned branch is a branch that exists in Supabase but no longer exists in GitHub. - * This method compares all branches in Supabase against all branches in GitHub to identify - * and remove orphaned branches. - * - * @internal - * This is an internal method used by the VectorActionUseCase. It should not be called directly. - * - * @param param - Execution parameters containing owner, repo, and Supabase config - * @param githubBranches - Array of all branch names that exist in GitHub (must be complete list, not just processed branches) - * - * @returns Array of Result objects indicating success/failure of the operation - * - * @remarks - * - Branch names are normalized (trimmed) before comparison - * - Comparison is case-sensitive (GitHub branch names are case-sensitive) - * - Invalid branch names (null, undefined, empty) are filtered out - * - If removal of a branch fails, the error is logged but processing continues - * - * @example - * ```typescript - * // This method is called internally by invoke() after processing branches - * // It receives ALL branches from GitHub, not just the ones being processed - * const allBranches = await branchRepository.getListOfBranches(owner, repo, token); - * const results = await removeOrphanedBranches(execution, allBranches); - * ``` - */ - private removeOrphanedBranches; - /** - * Detects errors, bugs, and code quality issues in a single file using ErrorDetector. - * - * This method uses the ErrorDetector agent to analyze a file for: - * - Syntax errors and bugs - * - Security vulnerabilities - * - Code quality issues - * - Best practice violations - * - * The analysis is limited to the target file only (analyzeOnlyTargetFile: true) to: - * - Reduce processing time - * - Lower API costs - * - Prevent analysis loops - * - Keep error detection focused and fast - * - * @internal - * This is a private method called during file processing. Error detection is optional - * and failures don't block file caching. The method is designed to be lightweight - * and focused on single-file analysis. - * - * @param param - Execution parameters containing AI config and repository info - * @param branch - Branch name where the file exists - * @param filePath - Path to the file to analyze - * @param fileContent - Content of the file to analyze - * - * @returns Object containing error counts by severity and error details, or null if: - * - AI configuration is missing - * - Error detection fails - * - File analysis cannot be completed - * - * @remarks - * - Uses maxTurns: 10 to prevent infinite loops in error detection - * - analyzeOnlyTargetFile: true ensures only the target file is analyzed (not dependencies) - * - Errors are categorized by severity: critical, high, medium, low - * - Error types are extracted and stored for filtering/searching - * - Full error details are stored as JSON payload for detailed analysis - * - * @example - * ```typescript - * const errorInfo = await detectErrorsForFile(execution, 'develop', 'src/file.ts', content); - * // errorInfo = { error_counter_total: 5, error_counter_critical: 1, ... } - * ``` - */ - private detectErrorsForFile; -} diff --git a/build/github_action/src/usecase/steps/commit/__tests__/notify_new_commit_on_issue_use_case.test.d.ts b/build/github_action/src/usecase/steps/commit/__tests__/notify_new_commit_on_issue_use_case.test.d.ts new file mode 100644 index 00000000..cb0ff5c3 --- /dev/null +++ b/build/github_action/src/usecase/steps/commit/__tests__/notify_new_commit_on_issue_use_case.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/github_action/src/usecase/steps/common/services/codebase_analyzer.d.ts b/build/github_action/src/usecase/steps/common/services/codebase_analyzer.d.ts deleted file mode 100644 index 5a63f75d..00000000 --- a/build/github_action/src/usecase/steps/common/services/codebase_analyzer.d.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { Execution } from '../../../../data/model/execution'; -import { AiRepository } from '../../../../data/repository/ai_repository'; -import { FileImportAnalyzer } from './file_import_analyzer'; -import { FileCacheManager } from './file_cache_manager'; -export interface FileAnalysisResult { - path: string; - description: string; - consumes: string[]; - consumed_by: string[]; -} -/** - * Service for analyzing codebase structure and generating file descriptions - */ -export declare class CodebaseAnalyzer { - private aiRepository; - private fileImportAnalyzer; - private fileCacheManager; - constructor(aiRepository: AiRepository, fileImportAnalyzer: FileImportAnalyzer, fileCacheManager: FileCacheManager); - /** - * Generate codebase analysis with file descriptions and relationships - * This runs before the main reasoning loop to provide context - * Uses relationship map built from imports + AI descriptions in batches - */ - generateCodebaseAnalysis(param: Execution, repositoryFiles: Map, question: string): Promise; - /** - * Generate basic description from file path (fallback) - */ - generateBasicDescription(path: string): string; - /** - * Generate fallback file descriptions when AI analysis fails - */ - generateFallbackFileDescriptions(files: Array<[string, string]>): FileAnalysisResult[]; - /** - * Format codebase analysis for inclusion in AI context - */ - formatCodebaseAnalysisForContext(analysis: FileAnalysisResult[]): string; -} diff --git a/build/github_action/src/usecase/steps/common/services/comment_formatter.d.ts b/build/github_action/src/usecase/steps/common/services/comment_formatter.d.ts deleted file mode 100644 index c0013f16..00000000 --- a/build/github_action/src/usecase/steps/common/services/comment_formatter.d.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { ThinkStep, ProposedChange, FileAnalysis } from '../../../../data/model/think_response'; -import { ThinkTodoManager } from '../think_todo_manager'; -/** - * Service for formatting GitHub comments and code changes - */ -export declare class CommentFormatter { - private readonly GITHUB_COMMENT_MAX_LENGTH; - /** - * Format the complete reasoning comment for GitHub - */ - formatReasoningComment(question: string, description: string, steps: ThinkStep[], analyzedFiles: Map, proposedChanges: ProposedChange[], finalAnalysis: string, totalIterations: number, todoManager: ThinkTodoManager): string; - /** - * Format a single proposed change - */ - formatProposedChange(change: ProposedChange, index: number): string; - /** - * Detect programming language from file path/extension - */ - detectLanguageFromPath(filePath: string): string; - /** - * Get emoji for action type - */ - getActionEmoji(action: string): string; - /** - * Format action name for display - */ - formatActionName(action: string): string; - /** - * Get emoji for change type - */ - getChangeTypeEmoji(changeType: string): string; -} diff --git a/build/github_action/src/usecase/steps/common/services/file_cache_manager.d.ts b/build/github_action/src/usecase/steps/common/services/file_cache_manager.d.ts deleted file mode 100644 index 3ae0e95f..00000000 --- a/build/github_action/src/usecase/steps/common/services/file_cache_manager.d.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { Execution } from '../../../../data/model/execution'; -import { SupabaseRepository } from '../../../../data/repository/supabase_repository'; -import { CachedFileInfo } from './types'; -/** - * Service for managing AI file cache in Supabase - */ -export declare class FileCacheManager { - private supabaseRepository; - /** - * Normalize file path for consistent comparison - * Removes leading ./ and normalizes path separators - */ - private normalizePath; - /** - * Calculate SHA256 hash of file content - */ - calculateFileSHA(content: string): string; - /** - * Initialize Supabase repository if config is available - */ - initSupabaseRepository(param: Execution): SupabaseRepository | null; - /** - * Load cache from Supabase (or return empty map if Supabase not available) - * Uses normalized paths for consistent lookup - */ - loadAICache(param: Execution): Promise>; - /** - * Get cached file info by path (with path normalization) - */ - getCachedFile(cache: Map, filePath: string): CachedFileInfo | undefined; - /** - * Save cache entry to Supabase - * Normalizes paths before saving - */ - saveAICacheEntry(param: Execution, filePath: string, fileInfo: CachedFileInfo, consumes: string[], consumedBy: string[]): Promise; -} diff --git a/build/github_action/src/usecase/steps/common/services/file_import_analyzer.d.ts b/build/github_action/src/usecase/steps/common/services/file_import_analyzer.d.ts deleted file mode 100644 index f2b5da10..00000000 --- a/build/github_action/src/usecase/steps/common/services/file_import_analyzer.d.ts +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Service for extracting imports and building file relationship maps - * Supports multiple programming languages - */ -export declare class FileImportAnalyzer { - /** - * Extract imports from a file regardless of programming language - */ - extractImportsFromFile(filePath: string, content: string): string[]; - /** - * Resolve relative import path to absolute path - */ - resolveRelativePath(baseDir: string, relativePath: string): string; - /** - * Build relationship map from all files by extracting imports - * Also builds reverse map (consumed_by) - */ - buildRelationshipMap(repositoryFiles: Map): { - consumes: Map; - consumedBy: Map; - }; -} diff --git a/build/github_action/src/usecase/steps/common/services/file_search_service.d.ts b/build/github_action/src/usecase/steps/common/services/file_search_service.d.ts deleted file mode 100644 index 14be3a66..00000000 --- a/build/github_action/src/usecase/steps/common/services/file_search_service.d.ts +++ /dev/null @@ -1,13 +0,0 @@ -/** - * Service for building file indexes and searching files - */ -export declare class FileSearchService { - /** - * Build file index for quick lookup by filename or directory - */ - buildFileIndex(files: Map): Map; - /** - * Search files by search terms (filename, directory, pattern, or content) - */ - searchFiles(searchTerms: string[], fileIndex: Map, repositoryFiles?: Map): string[]; -} diff --git a/build/github_action/src/usecase/steps/common/services/types.d.ts b/build/github_action/src/usecase/steps/common/services/types.d.ts deleted file mode 100644 index 69de0d14..00000000 --- a/build/github_action/src/usecase/steps/common/services/types.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -/** - * Shared types for codebase analysis services - */ -export interface FileRelationshipMap { - consumes: Map; - consumedBy: Map; -} diff --git a/build/github_action/src/usecase/steps/common/think_code_manager.d.ts b/build/github_action/src/usecase/steps/common/think_code_manager.d.ts deleted file mode 100644 index 465bde74..00000000 --- a/build/github_action/src/usecase/steps/common/think_code_manager.d.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { ProposedChange } from '../../../data/model/think_response'; -/** - * Manages virtual code state - keeps files in memory and applies proposed changes - * so subsequent reasoning steps can see the accumulated progress - */ -export declare class ThinkCodeManager { - private originalFiles; - private virtualFiles; - private appliedChanges; - private allAppliedChanges; - /** - * Initialize with original repository files - */ - initialize(originalFiles: Map): void; - /** - * Get current state of a file (with applied changes) - */ - getFileContent(filePath: string): string | undefined; - /** - * Get all virtual files - */ - getAllFiles(): Map; - /** - * Check if a file has been modified - */ - isFileModified(filePath: string): boolean; - /** - * Get changes applied to a specific file - */ - getFileChanges(filePath: string): ProposedChange[]; - /** - * Apply a proposed change to the virtual codebase - */ - applyChange(change: ProposedChange): boolean; - /** - * Check if a change has already been applied (to avoid duplicates) - */ - hasChangeBeenApplied(change: ProposedChange): boolean; - /** - * Get summary of all applied changes - */ - getChangesSummary(): string; - /** - * Get context about what has changed for the AI - */ - getContextForAI(): string; - /** - * Simple similarity check for change descriptions - */ - private areSimilar; - /** - * Get statistics - */ - getStats(): { - totalFiles: number; - modifiedFiles: number; - totalChanges: number; - }; -} diff --git a/build/github_action/src/usecase/steps/common/think_todo_manager.d.ts b/build/github_action/src/usecase/steps/common/think_todo_manager.d.ts deleted file mode 100644 index 72b63399..00000000 --- a/build/github_action/src/usecase/steps/common/think_todo_manager.d.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { ThinkTodoItem, TodoStatus } from '../../../data/model/think_response'; -import { ProposedChange } from '../../../data/model/think_response'; -/** - * Manages TODO list for the reasoning process - * Similar to how the assistant tracks high-level tasks vs iterative steps - */ -export declare class ThinkTodoManager { - private todos; - private nextId; - /** - * Initialize with optional initial todos - */ - initialize(initialTodos?: Array<{ - content: string; - status?: TodoStatus; - }>): void; - /** - * Create a new TODO item - */ - createTodo(content: string, status?: TodoStatus): ThinkTodoItem; - /** - * Update an existing TODO item - */ - updateTodo(id: string, updates: { - status?: TodoStatus; - notes?: string; - related_files?: string[]; - related_changes?: string[]; - }): boolean; - /** - * Get all TODOs - */ - getAllTodos(): ThinkTodoItem[]; - /** - * Get TODOs by status - */ - getTodosByStatus(status: ThinkTodoItem['status']): ThinkTodoItem[]; - /** - * Get active TODOs (pending or in_progress) - */ - getActiveTodos(): ThinkTodoItem[]; - /** - * Get completion statistics - */ - getStats(): { - total: number; - pending: number; - in_progress: number; - completed: number; - cancelled: number; - completion_rate: number; - }; - /** - * Get formatted TODO list for AI context - */ - getContextForAI(): string; - /** - * Link a TODO to proposed changes - */ - linkTodoToChanges(todoId: string, changes: ProposedChange[]): void; - /** - * Auto-update TODO status based on progress - * If changes are applied for a TODO, mark it as in_progress or completed - */ - autoUpdateFromChanges(changes: ProposedChange[]): void; - /** - * Get summary for final report - */ - getSummary(): string; -} diff --git a/build/github_action/src/usecase/steps/common/think_use_case_2.d.ts b/build/github_action/src/usecase/steps/common/think_use_case_2.d.ts deleted file mode 100644 index 0fceaf79..00000000 --- a/build/github_action/src/usecase/steps/common/think_use_case_2.d.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { Execution } from '../../../data/model/execution'; -import { Result } from '../../../data/model/result'; -import { ParamUseCase } from '../../base/param_usecase'; -export declare class ThinkUseCase implements ParamUseCase { - taskId: string; - private aiRepository; - private fileRepository; - private issueRepository; - private fileImportAnalyzer; - private fileCacheManager; - private codebaseAnalyzer; - private fileSearchService; - private commentFormatter; - private readonly MAX_ITERATIONS; - private readonly MAX_FILES_TO_ANALYZE; - private readonly MAX_CONSECUTIVE_SEARCHES; - private readonly MAX_FILES_PER_READ; - constructor(); - invoke(param: Execution): Promise; - private getIssueDescription; - private performReasoningStep; - private generateFinalAnalysis; - /** - * Detect generic search terms that are too common and not useful - */ - private detectGenericSearchTerms; -} diff --git a/build/github_action/src/usecase/steps/issue/__tests__/assign_members_to_issue_use_case.test.d.ts b/build/github_action/src/usecase/steps/issue/__tests__/assign_members_to_issue_use_case.test.d.ts new file mode 100644 index 00000000..cb0ff5c3 --- /dev/null +++ b/build/github_action/src/usecase/steps/issue/__tests__/assign_members_to_issue_use_case.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/github_action/src/usecase/steps/issue/__tests__/close_issue_after_merging_use_case.test.d.ts b/build/github_action/src/usecase/steps/issue/__tests__/close_issue_after_merging_use_case.test.d.ts new file mode 100644 index 00000000..cb0ff5c3 --- /dev/null +++ b/build/github_action/src/usecase/steps/issue/__tests__/close_issue_after_merging_use_case.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/github_action/src/usecase/steps/issue/__tests__/label_deploy_added_use_case.test.d.ts b/build/github_action/src/usecase/steps/issue/__tests__/label_deploy_added_use_case.test.d.ts new file mode 100644 index 00000000..cb0ff5c3 --- /dev/null +++ b/build/github_action/src/usecase/steps/issue/__tests__/label_deploy_added_use_case.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/github_action/src/usecase/steps/issue/__tests__/link_issue_project_use_case.test.d.ts b/build/github_action/src/usecase/steps/issue/__tests__/link_issue_project_use_case.test.d.ts new file mode 100644 index 00000000..cb0ff5c3 --- /dev/null +++ b/build/github_action/src/usecase/steps/issue/__tests__/link_issue_project_use_case.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/github_action/src/usecase/steps/issue/__tests__/move_issue_to_in_progress_use_case.test.d.ts b/build/github_action/src/usecase/steps/issue/__tests__/move_issue_to_in_progress_use_case.test.d.ts new file mode 100644 index 00000000..cb0ff5c3 --- /dev/null +++ b/build/github_action/src/usecase/steps/issue/__tests__/move_issue_to_in_progress_use_case.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/github_action/src/usecase/steps/issue/__tests__/prepare_branches_use_case.test.d.ts b/build/github_action/src/usecase/steps/issue/__tests__/prepare_branches_use_case.test.d.ts new file mode 100644 index 00000000..cb0ff5c3 --- /dev/null +++ b/build/github_action/src/usecase/steps/issue/__tests__/prepare_branches_use_case.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/github_action/src/usecase/steps/issue/__tests__/remove_issue_branches_use_case.test.d.ts b/build/github_action/src/usecase/steps/issue/__tests__/remove_issue_branches_use_case.test.d.ts new file mode 100644 index 00000000..cb0ff5c3 --- /dev/null +++ b/build/github_action/src/usecase/steps/issue/__tests__/remove_issue_branches_use_case.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/github_action/src/usecase/steps/issue/__tests__/remove_not_needed_branches_use_case.test.d.ts b/build/github_action/src/usecase/steps/issue/__tests__/remove_not_needed_branches_use_case.test.d.ts new file mode 100644 index 00000000..cb0ff5c3 --- /dev/null +++ b/build/github_action/src/usecase/steps/issue/__tests__/remove_not_needed_branches_use_case.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/github_action/src/usecase/steps/pull_request/__tests__/link_pull_request_issue_use_case.test.d.ts b/build/github_action/src/usecase/steps/pull_request/__tests__/link_pull_request_issue_use_case.test.d.ts new file mode 100644 index 00000000..cb0ff5c3 --- /dev/null +++ b/build/github_action/src/usecase/steps/pull_request/__tests__/link_pull_request_issue_use_case.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/github_action/src/usecase/steps/pull_request/__tests__/link_pull_request_project_use_case.test.d.ts b/build/github_action/src/usecase/steps/pull_request/__tests__/link_pull_request_project_use_case.test.d.ts new file mode 100644 index 00000000..cb0ff5c3 --- /dev/null +++ b/build/github_action/src/usecase/steps/pull_request/__tests__/link_pull_request_project_use_case.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/github_action/src/usecase/steps/pull_request/__tests__/update_pull_request_description_use_case.test.d.ts b/build/github_action/src/usecase/steps/pull_request/__tests__/update_pull_request_description_use_case.test.d.ts new file mode 100644 index 00000000..cb0ff5c3 --- /dev/null +++ b/build/github_action/src/usecase/steps/pull_request/__tests__/update_pull_request_description_use_case.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/github_action/src/usecase/steps/pull_request/check_changes_pull_request_size_use_case.d.ts b/build/github_action/src/usecase/steps/pull_request/check_changes_pull_request_size_use_case.d.ts deleted file mode 100644 index 139ed5e4..00000000 --- a/build/github_action/src/usecase/steps/pull_request/check_changes_pull_request_size_use_case.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Execution } from "../../../data/model/execution"; -import { Result } from "../../../data/model/result"; -import { ParamUseCase } from "../../base/param_usecase"; -export declare class CheckChangesPullRequestSizeUseCase implements ParamUseCase { - taskId: string; - private branchRepository; - private issueRepository; - private projectRepository; - invoke(param: Execution): Promise; -} diff --git a/build/github_action/src/utils/__tests__/setup_files.test.d.ts b/build/github_action/src/utils/__tests__/setup_files.test.d.ts new file mode 100644 index 00000000..cb0ff5c3 --- /dev/null +++ b/build/github_action/src/utils/__tests__/setup_files.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/github_action/src/utils/constants.d.ts b/build/github_action/src/utils/constants.d.ts index f9c9b80c..a83f4ea2 100644 --- a/build/github_action/src/utils/constants.d.ts +++ b/build/github_action/src/utils/constants.d.ts @@ -1,6 +1,5 @@ -export declare const COMMAND = "giik"; -export declare const TITLE = "Giik"; -export declare const REPO_URL = "https://github.com/landamessenger/git-board-flow"; +export declare const TITLE = "Copilot"; +export declare const REPO_URL = "https://github.com/vypdev/copilot"; /** Default OpenCode model: provider/modelID (e.g. opencode/kimi-k2.5-free). Reuse for CLI, action and Ai fallbacks. */ export declare const OPENCODE_DEFAULT_MODEL = "opencode/kimi-k2.5-free"; /** Timeout in ms for OpenCode HTTP requests (session create, message, diff). Agent calls can be slow (e.g. plan analyzing repo). */ @@ -202,8 +201,8 @@ export declare const ACTIONS: { readonly DETECT_POTENTIAL_PROBLEMS: "detect_potential_problems_action"; readonly RECOMMEND_STEPS: "recommend_steps_action"; }; -/** Hidden HTML comment prefix for bugbot findings (issue/PR comments). Format: */ -export declare const BUGBOT_MARKER_PREFIX = "gbf-bugbot"; +/** Hidden HTML comment prefix for bugbot findings (issue/PR comments). Format: */ +export declare const BUGBOT_MARKER_PREFIX = "copilot-bugbot"; /** Max number of individual bugbot comments to create per issue/PR. Excess findings get one summary comment suggesting to review locally. */ export declare const BUGBOT_MAX_COMMENTS = 20; /** Minimum severity to publish (findings below this are dropped). Order: high > medium > low > info. */ diff --git a/build/github_action/src/utils/reasoning_visualizer.d.ts b/build/github_action/src/utils/reasoning_visualizer.d.ts deleted file mode 100644 index 8c909e33..00000000 --- a/build/github_action/src/utils/reasoning_visualizer.d.ts +++ /dev/null @@ -1,61 +0,0 @@ -export declare class ReasoningVisualizer { - private currentIteration; - private maxIterations; - private startTime; - private lastAction; - private todoStats; - private filesRead; - private filesAnalyzed; - private changesApplied; - initialize(maxIterations: number): void; - updateIteration(iteration: number): void; - updateTodoStats(stats: { - total: number; - pending: number; - in_progress: number; - completed: number; - }): void; - updateFilesRead(count: number): void; - updateFilesAnalyzed(count: number): void; - updateChangesApplied(count: number): void; - /** - * Show a clean header for the reasoning process - */ - showHeader(question: string): void; - /** - * Show current iteration status with progress bar - */ - showIterationStatus(action: string, reasoning: string): void; - /** - * Show TODO status - */ - showTodoStatus(): void; - /** - * Show file and change statistics - */ - showStats(): void; - /** - * Show action result summary - */ - showActionResult(action: string, result: { - success: boolean; - message: string; - details?: string[]; - }): void; - /** - * Show completion summary - */ - showCompletion(_finalAnalysis?: string): void; - /** - * Create a visual progress bar - */ - private createProgressBar; - /** - * Get emoji for action type - */ - private getActionEmoji; - /** - * Clear current line and show updated status - */ - updateStatus(action: string, reasoning: string): void; -} diff --git a/build/github_action/src/utils/setup_files.d.ts b/build/github_action/src/utils/setup_files.d.ts new file mode 100644 index 00000000..c870c050 --- /dev/null +++ b/build/github_action/src/utils/setup_files.d.ts @@ -0,0 +1,16 @@ +/** + * Ensure .github, .github/workflows and .github/ISSUE_TEMPLATE exist; create them if missing. + * @param cwd - Directory (repo root) + */ +export declare function ensureGitHubDirs(cwd: string): void; +/** + * Copy setup files from setup/ to repo (.github/ workflows, ISSUE_TEMPLATE, pull_request_template.md, .env at root). + * Skips files that already exist at destination (no overwrite). + * Logs each file copied or skipped. No-op if setup/ does not exist. + * @param cwd - Repo root + * @returns { copied, skipped } + */ +export declare function copySetupFiles(cwd: string): { + copied: number; + skipped: number; +}; diff --git a/build/github_action/src/utils/task_emoji.d.ts b/build/github_action/src/utils/task_emoji.d.ts new file mode 100644 index 00000000..1291586f --- /dev/null +++ b/build/github_action/src/utils/task_emoji.d.ts @@ -0,0 +1 @@ +export declare function getTaskEmoji(taskId: string): string; diff --git a/docs.json b/docs.json index 8803f8c7..7c0e7641 100644 --- a/docs.json +++ b/docs.json @@ -1,70 +1,178 @@ { - "name": "Git Board Flow", + "name": "Copilot", "description": "A tool for managing Git workflow and board integration", "tabs": [ - { "id": "root", "title": "Home", "href": "/" }, - { "id": "issues", "title": "Issues", "href": "/issues" }, - { "id": "pull-requests", "title": "Pull Requests", "href": "/pull-requests" }, - { "id": "single-action", "title": "Single Actions", "href": "/single-actions" } + { + "id": "root", + "title": "Home", + "href": "/" + }, + { + "id": "issues", + "title": "Issues", + "href": "/issues" + }, + { + "id": "pull-requests", + "title": "Pull Requests", + "href": "/pull-requests" + }, + { + "id": "single-action", + "title": "Single Actions", + "href": "/single-actions" + } ], "sidebar": [ { "group": "Getting Started", "tab": "root", "pages": [ - { "title": "Introduction", "href": "/", "icon": "rocket" }, - { "title": "How To Use", "href": "/how-to-use", "icon": "list-check" }, - { "title": "Features & Capabilities", "href": "/features", "icon": "list" }, - { "title": "Authentication", "href": "/authentication", "icon": "key" }, - { "title": "OpenCode (AI)", "href": "/opencode-integration", "icon": "cpu" }, - { "title": "Testing OpenCode Plan Locally", "href": "/testing-opencode-plan-locally", "icon": "terminal" }, - { "title": "Configuration", "href": "/configuration", "icon": "gear" }, - { "title": "Troubleshooting", "href": "/troubleshooting", "icon": "wrench" } + { + "title": "Introduction", + "href": "/", + "icon": "rocket" + }, + { + "title": "How To Use", + "href": "/how-to-use", + "icon": "list-check" + }, + { + "title": "Features & Capabilities", + "href": "/features", + "icon": "list" + }, + { + "title": "Authentication", + "href": "/authentication", + "icon": "key" + }, + { + "title": "OpenCode (AI)", + "href": "/opencode-integration", + "icon": "cpu" + }, + { + "title": "Testing OpenCode Plan Locally", + "href": "/testing-opencode-plan-locally", + "icon": "terminal" + }, + { + "title": "Configuration", + "href": "/configuration", + "icon": "gear" + }, + { + "title": "Troubleshooting", + "href": "/troubleshooting", + "icon": "wrench" + } ] }, { "group": "Issues", "tab": "issues", "pages": [ - { "title": "General", "href": "/issues/", "icon": "book" }, - { "title": "Configuration", "href": "/issues/configuration", "icon": "gear" } + { + "title": "General", + "href": "/issues", + "icon": "book" + }, + { + "title": "Configuration", + "href": "/issues/configuration", + "icon": "gear" + } ] }, { "group": "Issue Types", "tab": "issues", "pages": [ - { "title": "Documentation", "href": "/issues/type/docs", "icon": "file-text" }, - { "title": "Chore", "href": "/issues/type/chore", "icon": "wrench" }, - { "title": "Feature", "href": "/issues/type/feature", "icon": "lightbulb" }, - { "title": "Bugfix", "href": "/issues/type/bugfix", "icon": "bug" }, - { "title": "Hotfix", "href": "/issues/type/hotfix", "icon": "fire" }, - { "title": "Release", "href": "/issues/type/release", "icon": "tag" } + { + "title": "Documentation", + "href": "/issues/type/docs", + "icon": "file-text" + }, + { + "title": "Chore", + "href": "/issues/type/chore", + "icon": "wrench" + }, + { + "title": "Feature", + "href": "/issues/type/feature", + "icon": "lightbulb" + }, + { + "title": "Bugfix", + "href": "/issues/type/bugfix", + "icon": "bug" + }, + { + "title": "Hotfix", + "href": "/issues/type/hotfix", + "icon": "fire" + }, + { + "title": "Release", + "href": "/issues/type/release", + "icon": "tag" + } ] }, { "group": "Pull Requests", "tab": "pull-requests", "pages": [ - { "title": "Overview", "href": "/pull-requests", "icon": "book" }, - { "title": "Configuration", "href": "/pull-requests/configuration", "icon": "gear" }, - { "title": "AI PR description", "href": "/pull-requests/ai-description", "icon": "file-text" } + { + "title": "Overview", + "href": "/pull-requests", + "icon": "book" + }, + { + "title": "Configuration", + "href": "/pull-requests/configuration", + "icon": "gear" + }, + { + "title": "AI PR description", + "href": "/pull-requests/ai-description", + "icon": "file-text" + } ] }, { "group": "Single Actions", "tab": "single-action", "pages": [ - { "title": "Overview", "href": "/single-actions", "icon": "play" }, - { "title": "Configuration", "href": "/single-actions/configuration", "icon": "gear" }, - { "title": "Workflow & CLI", "href": "/single-actions/workflow-and-cli", "icon": "terminal" } + { + "title": "Overview", + "href": "/single-actions", + "icon": "play" + }, + { + "title": "Configuration", + "href": "/single-actions/configuration", + "icon": "gear" + }, + { + "title": "Workflow & CLI", + "href": "/single-actions/workflow-and-cli", + "icon": "terminal" + } ] }, { "group": "Support", "pages": [ - { "title": "Support", "href": "/support", "icon": "help-circle" } + { + "title": "Support", + "href": "/support", + "icon": "help-circle" + } ] } ] -} +} \ No newline at end of file diff --git a/docs/authentication.mdx b/docs/authentication.mdx index f4bb58b9..99f17d4a 100644 --- a/docs/authentication.mdx +++ b/docs/authentication.mdx @@ -3,7 +3,7 @@ title: Authentication description: Securely authenticate your workflows using personal access tokens (PATs). --- -Git Board Flow requires a fine-grained personal access token to perform certain actions, such as creating branches, updating pull requests, or managing project boards. +Copilot requires a fine-grained personal access token to perform certain actions, such as creating branches, updating pull requests, or managing project boards. Originally, the workflow also made use of the GITHUB_TOKEN for some basic tasks executed within the workflow's scope. However, to simplify the configuration and maintain a single unified bot, the use of this token has been removed, leaving only the necessary PAT. @@ -13,7 +13,7 @@ Git Board Flow requires a fine-grained personal access token to perform certain Choose which account will be used to create your PAT. This account will act as your bot. - For individual developers, it is recommended to use your own account as the bot. - - In organizations and enterprise accounts, it is better to use a separate, dedicated account. For example, this project belongs to [**landamessenger**](https://github.com/landamessenger), and the selected bot account is [**landa-bot**](https://github.com/landa-bot). + - In organizations and enterprise accounts, it is better to use a separate, dedicated account. For example, this project belongs to [**vypdev**](https://github.com/vypdev), and the selected bot account is [**vypbot**](https://github.com/vypbot). @@ -30,7 +30,7 @@ Git Board Flow requires a fine-grained personal access token to perform certain - If your bot account does not belong to an organization (individual developer), you should keep your own account selected when creating the token (this is usually the default value, so you likely won’t need to change it). - If your account belongs to an organization, make sure to select the organization that this token will operate under. - In the **Repository access** section, you need to select the scope for which you want this token to operate. We recommend choosing **All repositories** to quickly configure Git Board Flow on any repository the bot account has access to. + In the **Repository access** section, you need to select the scope for which you want this token to operate. We recommend choosing **All repositories** to quickly configure Copilot on any repository the bot account has access to. Set these permissions for the repository: @@ -65,7 +65,7 @@ Git Board Flow requires a fine-grained personal access token to perform certain It’s time to create a new Secret: If your bot account does **not** belong to an organization (individual developer): - - Go to the repository where you want to implement Git Board Flow. + - Go to the repository where you want to implement Copilot. - Then, navigate to **Settings**. - In the left sidebar, click on **Secrets and variables**, then **Actions**. - Click **New repository secret**. @@ -81,10 +81,10 @@ Git Board Flow requires a fine-grained personal access token to perform certain - Finally, click **Add secret**. - In each workflow that consumes Git Board Flow, make sure to pass the PAT you just created with the `token` property: + In each workflow that consumes Copilot, make sure to pass the PAT you just created with the `token` property: ```yml - name: Git Board Flow - Issue + name: Copilot - Issue on: issues: @@ -95,7 +95,7 @@ Git Board Flow requires a fine-grained personal access token to perform certain name: Git Board - Issue runs-on: ubuntu-latest steps: - - uses: landamessenger/git-board-flow@v1 + - uses: vypdev/copilot@v1 with: project-ids: 1,2 token: ${{ secrets.PAT }} diff --git a/docs/configuration.mdx b/docs/configuration.mdx index 10334018..08a37cb7 100644 --- a/docs/configuration.mdx +++ b/docs/configuration.mdx @@ -1,11 +1,11 @@ --- title: Configuration -description: Detailed configuration options for Git Board Flow +description: Detailed configuration options for Copilot --- # Configuration Options -Git Board Flow provides extensive configuration options to customize your workflow. Use the tabs below to jump to the category you need. +Copilot provides extensive configuration options to customize your workflow. Use the tabs below to jump to the category you need. diff --git a/docs/features.mdx b/docs/features.mdx index 991f5db8..f10c6fe1 100644 --- a/docs/features.mdx +++ b/docs/features.mdx @@ -1,13 +1,13 @@ --- title: Features & Capabilities -description: Complete reference of what the Git Board Flow GitHub Action does +description: Complete reference of what the Copilot GitHub Action does --- # Features & Capabilities -This page describes **every function** the Git Board Flow GitHub Action provides: workflow-triggered behavior (issues, pull requests, pushes) and **single actions** you can run on demand. +This page describes **every function** the Copilot GitHub Action provides: workflow-triggered behavior (issues, pull requests, pushes) and **single actions** you can run on demand. - + When you open, edit, or label issues: branch creation, project linking, assignees, issue type, size labels, and comments. @@ -17,7 +17,7 @@ This page describes **every function** the Git Board Flow GitHub Action provides On every push: commit notifications on the issue, prefix check, reopen option, size & progress labels (with OpenCode). Details below. - + --- @@ -109,11 +109,11 @@ Configuration: `opencode-server-url`, `opencode-model`, and optionally `opencode ## Workflow concurrency and sequential execution - - **Sequential runs:** When a new run starts, the action **waits** for any previous run of the **same workflow name** to finish. Runs of the same workflow (e.g. "Git Board Flow - Issue") execute one after another instead of in parallel or being cancelled — something GitHub does not offer natively. - + + **Sequential runs:** When a new run starts, the action **waits** for any previous run of the **same workflow name** to finish. Runs of the same workflow (e.g. "Copilot - Issue") execute one after another instead of in parallel or being cancelled — something GitHub does not offer natively. + -GitHub's native [concurrency](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#concurrency) lets you cancel in-progress runs when a new one starts (`cancel-in-progress: true`). Git Board Flow adds **sequential execution** for the same workflow: when a new run starts, the action waits for any previous run of the same workflow name to finish before doing its work. +GitHub's native [concurrency](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#concurrency) lets you cancel in-progress runs when a new one starts (`cancel-in-progress: true`). Copilot adds **sequential execution** for the same workflow: when a new run starts, the action waits for any previous run of the same workflow name to finish before doing its work. ### How it works @@ -127,18 +127,18 @@ So you get a **per-workflow queue**: multiple triggers for the same workflow (e. ### Example ```yaml -name: Git Board Flow - Issue +name: Copilot - Issue on: issues: types: [opened, edited, labeled, unlabeled] jobs: - git-board-flow-issues: + copilot-issues: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: landamessenger/git-board-flow@master + - uses: vypdev/copilot@master with: token: ${{ secrets.PAT }} project-ids: '2,3' diff --git a/docs/how-to-use.mdx b/docs/how-to-use.mdx index 37a0759a..7c0611e0 100644 --- a/docs/how-to-use.mdx +++ b/docs/how-to-use.mdx @@ -1,50 +1,230 @@ --- title: How To Use -description: Steps for setting up Git Board Flow in your repository +description: Quick setup with copilot setup, then customize labels, templates, and workflows. --- -Follow these steps to set up Git Board Flow in your repository: +## Quick installation (CLI) + +You can install the Copilot CLI **from any directory**. For example, from your home or projects folder: + +```bash +git clone https://github.com/vypdev/copilot.git +cd copilot +npm install . -g +``` + +If the repo does not include the compiled `build/` folder (e.g. it is gitignored), run `npm install` and `npm run build` before `npm install . -g`. + +Once installed, the `copilot` command is available globally. **All Copilot CLI commands** (including `copilot setup`, `copilot check-progress -i 123`, etc.) must be run **from inside the repository** where you want Copilot to run. That repository must have a **`.env`** file in its root with **`PERSONAL_ACCESS_TOKEN`** set so the CLI can access the repo. See [CLI commands](/single-actions/workflow-and-cli). + +--- + +## Tutorial: Get Copilot running in three steps - - Define a personal access token to interact with issues, pull requests and boards. - - - - Set up your repository's branch structure: - - **Primary Branch**: Default is `master` (or `main` for newer repositories) - - **Development Branch**: Default is `develop` - - You can customize these branch names in the configuration. These branches will serve as the foundation for your development workflow, where feature, bugfix, hotfix, release, docs and chore branches will be created from and merged back into. + + The action needs a **Personal Access Token** to manage issues, branches, projects, and workflows. You must create it manually; `copilot setup` does not create it. + Follow the [Authentication](/authentication) guide to create a **fine-grained PAT** with the right permissions (Actions, Administration, Contents, Issues, Metadata, Pull requests, etc.) and store it as a secret (e.g. `PAT`) in your repository or organization. - - Configure the following essential labels in your repository: - - **Type Labels**: For categorizing issues (e.g., `feature`, `enhancement`, `bug`, `bugfix`, `hotfix`, `release`, `docs`, `documentation`, `chore`, `maintenance`) - - **Action Labels**: For performing different actions (e.g., `branched`, `deploy`, `deployed`) - - **Priority Labels**: For issue prioritization (e.g., `priority: high`, `priority: medium`, `priority: low`) - - **Size Labels**: For control task sizes (e.g., `size: XS`, `size: S`, `size: M`, `size: L`, `size: XL`, `size: XXL`) - - These labels will be used by the action to automate workflows and organize your tasks effectively. - + + Go to the **root of the repository** where you want Copilot (clone it if needed), then run: - - Create issue templates to standardize task creation (in `.github/ISSUE_TEMPLATE/`): - - **Feature**: `feature_request.yml` — use labels such as `enhancement`, `feature`; add `branched` when the user should get a branch, or set `branch-management-always: true`. - - **Bugfix**: `bug_report.yml` — use labels `bug`, `bugfix`; add `branched` if needed. - - **Docs**: `doc_update.yml` — use labels `documentation`, `docs`. - - **Chore / maintenance**: `chore_task.yml` — use labels `chore`, `maintenance`. - - **Hotfix**: `hotfix.yml` — use labels `hotfix`, `branched` (branch is created from main at latest tag). - - **Release**: `release.yml` — use labels `release`, `branched` (branch is created from develop). - - **Help**: `help_request.yml` — for support requests (no branch). - Include the labels that match the [labels table](/issues#labels-by-issue-type-and-flow) so the action creates the correct branches and applies the right workflow. + ```bash + cd /path/to/your/repo + copilot setup + ``` + + **About the token the first time:** + The first time you run `copilot setup`, there will usually be **no `.env` file** in that repo with the PAT. The command will copy setup files (workflows, templates, etc.) but may fail or skip the step that needs GitHub access (labels, issue types). In that case: + + - Create a **`.env`** file in the **repository root** with your token: + ```bash + PERSONAL_ACCESS_TOKEN=your_fine_grained_token_here + ``` + - Run **`copilot setup` again**. This time it will have access to the repository and will create labels and issue types. + + Alternatively, you can create the `.env` file with `PERSONAL_ACCESS_TOKEN` and its value **before** the first run and execute `copilot setup` once; it will then complete all steps (copy files + create labels and issue types) in a single pass. + + `copilot setup` will: + - Create `.github/`, `.github/workflows/`, and `.github/ISSUE_TEMPLATE/` if they do not exist. + - Copy all files from the Copilot `setup/` folder into your repo (workflows, issue templates, pull request template). Existing files are **not** overwritten. + - Verify GitHub access using `PERSONAL_ACCESS_TOKEN` from `.env` (or the token you pass when prompted). + - Create all required **labels** in the repository (type, action, priority, size, progress 0%–100%). + - Create all required **issue types** in the organization (Task, Bug, Feature, Release, Hotfix, etc.), if your plan supports it. + + After this step you have a working baseline: labels, templates, and workflow files are in place. - - Add the GitHub Action to your repository by creating three workflow files (you can choose any names; common choices are `gbf_commit.yml`, `gbf_issue.yml`, `gbf_pr.yml` or names like "Git Board Flow - Commit", etc.): - 1. **Push (commit)** — runs on `push` to any branch: notifies issues of new commits, updates size and progress labels. Create e.g. `.github/workflows/gbf_commit.yml`. - 2. **Issues** — runs on `issues` (opened, edited, labeled, unlabeled): creates branches, links to projects, assignees. Create e.g. `.github/workflows/gbf_issue.yml`. - 3. **Pull requests** — runs on `pull_request`: links PR to issue, project, reviewers. Create e.g. `.github/workflows/gbf_pr.yml`. - See the [README](https://github.com/landamessenger/git-board-flow#quick-start) for full YAML examples. These workflows will then automatically manage branches, project boards, and the relationship between issues and code. + + You can tweak issue templates (text, dropdowns), workflow names, and branch names. The following points are **required** for the GitHub Action to behave correctly; the rest is optional. + + **Required for the action to work:** + - **Token**: Every workflow that runs Copilot must pass the `token` input (your PAT). Typically you set `token: ${{ secrets.PAT }}` in each Copilot step. Without it, the action cannot create branches, update issues, or call the API. + - **Workflow file names for release/hotfix**: When an issue has the **deploy** label, Copilot *dispatches* a workflow by **filename**. The action inputs `release-workflow` (default: `release_workflow.yml`) and `hotfix-workflow` (default: `hotfix_workflow.yml`) must match the **exact filenames** in `.github/workflows/`. If you rename `release_workflow.yml` or `hotfix_workflow.yml`, you **must** pass the new names to the action in the workflows that invoke Copilot (e.g. in `copilot_issue.yml` add `release-workflow: 'your_release.yml'` and `hotfix-workflow: 'your_hotfix.yml'`). + - **Deploy label**: The label that triggers the deploy flow is configured by the `deploy-label` input (default: `deploy`). The issue templates and your usage must use this same label when you want to run the release or hotfix workflow. + - **Branch names in workflows**: The Commit workflow (push) often excludes the main and development branches from running (e.g. `!master`, `!develop`). If you change the default branch names (e.g. `main-branch: 'main'`, `development-branch: 'develop'`), update the `push.branches` filter in `.github/workflows/copilot_commit.yml` so it excludes those same names; otherwise the action may run on every push to main/develop or never run on feature branches. + + **Optional but keep coherence:** + - **Labels**: If you change any label input (e.g. `feature-label`, `bugfix-label`, `deploy-label`), use the **same** label names in your issue templates (`labels:` in each `.yml`) and when labeling issues manually. Otherwise the action will not recognize the type or flow. + - **Branch name prefixes**: The action uses inputs like `feature-tree`, `bugfix-tree`, `release-tree`, `hotfix-tree` (defaults: `feature`, `bugfix`, `release`, `hotfix`) to create branch names. If you change them, branch names will follow the new prefixes; keep templates and docs in sync. + - **Project columns**: Default column names are "Todo" and "In Progress". If you rename columns in GitHub Projects, set the corresponding action inputs (`project-column-issue-created`, `project-column-issue-in-progress`, etc.) so the action moves issues/PRs to the correct columns. - \ No newline at end of file + + +--- + +## What lives in `setup/` (and what gets created) + +Everything under the `setup/` directory is copied into your repo by `copySetupFiles` (run during `copilot setup`). Below is a desglose of labels (with defaults), issue types, and the contents of `setup/` so you know what you can customize and what must stay consistent. + +### Coherence when customizing + +If you rename or change any of the following, keep these in sync: + +- **Label names** in the action inputs (e.g. in workflow `with:` or in repo/organization variables) must match the **labels** used in issue templates and on issues (e.g. `deploy`, `release`, `feature`). +- **Workflow filenames** for release and hotfix (e.g. `release_workflow.yml`) must match the action inputs `release-workflow` and `hotfix-workflow` wherever you call the action (e.g. in the Issue workflow that reacts to the deploy label). +- **Branch names** (main, develop, feature, bugfix, etc.) must match between the action inputs and any workflow filters (e.g. `push.branches` in the Commit workflow). + +--- + +## Labels created by `copilot setup` (default values) + +The setup creates the following labels. Names come from the action input defaults; colors and descriptions are set by the code. + +### Type and flow labels + +| Input key | Default label name | Purpose | +|-----------|--------------------|--------| +| `branch-management-launcher-label` | `branched` | Triggers branch creation when added to an issue | +| `feature-label` | `feature` | Feature branches | +| `enhancement-label` | `enhancement` | Treated like feature | +| `bug-label` | `bug` | Bug type | +| `bugfix-label` | `bugfix` | Bugfix branches | +| `hotfix-label` | `hotfix` | Hotfix branches (from main at tag) | +| `release-label` | `release` | Release branches (from develop) | +| `docs-label` | `docs` | Docs branches | +| `documentation-label` | `documentation` | Treated like docs | +| `chore-label` | `chore` | Chore branches | +| `maintenance-label` | `maintenance` | Treated like chore | +| `question-label` | `question` | Question issues (e.g. Think action) | +| `help-label` | `help` | Help request issues | +| `deploy-label` | `deploy` | Triggers release/hotfix workflow dispatch when added | +| `deployed-label` | `deployed` | Mark issue as deployed after workflow runs | + +### Priority labels + +| Input key | Default label name | +|-----------|---------------------| +| `priority-high-label` | `priority: high` | +| `priority-medium-label` | `priority: medium` | +| `priority-low-label` | `priority: low` | +| `priority-none-label` | `priority: none` | + +### Size labels + +| Input key | Default label name | +|-----------|---------------------| +| `size-xxl-label` | `size: XXL` | +| `size-xl-label` | `size: XL` | +| `size-l-label` | `size: L` | +| `size-m-label` | `size: M` | +| `size-s-label` | `size: S` | +| `size-xs-label` | `size: XS` | + +### Progress labels + +The setup creates **21 progress labels**: `0%`, `5%`, `10%`, … `100%`. Colors go from red (0%) to yellow (50%) to green (100%). These are used by the Check Progress action and commit steps to update issue progress. + +--- + +## Issue types created by `copilot setup` (defaults) + +For organizations that support issue types, the setup ensures these exist (name / description / color from action inputs): + +| Type | Default name | Default color | +|------|--------------|---------------| +| Task | Task | blue | +| Bug | Bug | orange | +| Feature | Feature | green | +| Documentation | Documentation | pink | +| Maintenance | Maintenance | purple | +| Hotfix | Hotfix | red | +| Release | Release | yellow | +| Question | Question | gray | +| Help | Help | purple | + +--- + +## Branch name prefixes (defaults) + +Used to build branch names (e.g. `feature/42-my-title`). Configurable via action inputs: + +| Input key | Default value | +|-----------|----------------| +| `main-branch` | `master` | +| `development-branch` | `develop` | +| `feature-tree` | `feature` | +| `bugfix-tree` | `bugfix` | +| `hotfix-tree` | `hotfix` | +| `release-tree` | `release` | +| `docs-tree` | `docs` | +| `chore-tree` | `chore` | + +--- + +## Contents of `setup/` (workflows, templates, PR template) + +### `setup/workflows/` + +All `.yml` / `.yaml` files here are copied to `.github/workflows/`. Default filenames and roles: + +| File | Purpose | +|------|--------| +| `copilot_issue.yml` | Runs on issue events (opened, edited, labeled, unlabeled, etc.): creates branches, links to projects, assignees, deploy trigger. | +| `copilot_pull_request.yml` | Runs on PR events: links PR to issue/project, reviewers, AI description, etc. | +| `copilot_commit.yml` | Runs on push (all branches except main/develop by default): notifies issue, updates size and progress labels, bugbot. | +| `copilot_issue_comment.yml` | Runs on issue comment: e.g. Think action (answer questions). | +| `copilot_pull_request_comment.yml` | Runs on PR review comment: e.g. translation checks. | +| `release_workflow.yml` | **Manual** (`workflow_dispatch`): release flow (version, changelog, tag, release, deployed). Filename must match the action input `release-workflow` (default: `release_workflow.yml`) so the Issue workflow can dispatch it when the **deploy** label is added. | +| `hotfix_workflow.yml` | **Manual** (`workflow_dispatch`): hotfix flow. Filename must match the action input `hotfix-workflow` (default: `hotfix_workflow.yml`). | + +Each Copilot workflow step passes at least `token` (and often `project-ids`, `opencode-model`, `debug` via vars). The **release** and **hotfix** workflows are **dispatched by the action** when an issue has the deploy label and the corresponding release/hotfix context (branch, version, etc.); they are not triggered by issue events directly. + +### `setup/ISSUE_TEMPLATE/` + +All files here are copied to `.github/ISSUE_TEMPLATE/`. + +| File | Purpose | +|------|--------| +| `config.yml` | Issue template config (e.g. `blank_issues_enabled`, contact link to Git-Flow). | +| `feature_request.yml` | Feature request; uses labels like `enhancement`, `feature`, `priority: low`. Add `branched` if you want a branch created automatically. | +| `bug_report.yml` | Bug report; uses `bug`, `bugfix`, `priority: high`. Add `branched` if needed. | +| `doc_update.yml` | Documentation; uses `documentation`, `docs`. | +| `chore_task.yml` | Chore/maintenance; uses `chore`, `maintenance`. | +| `help_request.yml` | Help request; uses `help` (no branch). | +| `hotfix.yml` | Hotfix; uses `hotfix`, `branched`, `priority: high`. Includes Base Version, Hotfix Version, Changelog. | +| `release.yml` | Release; uses `release`, `branched`, `priority: medium`. Includes Release Type, Version, Changelog. | + +The **labels** in each template must match the label names configured in the action (or your custom inputs). For example, if you change `deploy-label` to `ready-to-deploy`, then any template or process that adds the deploy trigger must use `ready-to-deploy`. + +### `setup/pull_request_template.md` + +Copied to `.github/pull_request_template.md`. Used as the default body for new PRs. The AI PR description feature can fill this structure; you can edit the sections (Summary, Related Issues, Scope, Technical Details, How to Test, etc.) to fit your repo. No Copilot logic depends on specific headings; only the deploy/release/hotfix flows depend on **workflow filenames** and **label names**. + +### `setup/.env` + +If present, copied to the repository root as `.env`. Useful for local CLI (e.g. `PAT=...`). Not used by the GitHub Action (secrets come from the workflow). + +--- + +## Optional: Configure projects, AI, and workflows + +After the tutorial and file adaption, you can: + +- Set **repository or organization variables** (e.g. `PROJECT_IDS`, `OPENCODE_MODEL`, `DEBUG`) and reference them in the Copilot workflow steps (`project-ids: ${{ vars.PROJECT_IDS }}`, etc.). +- Adjust **project column names** and **branch names** via action inputs so the action moves issues/PRs to the right columns and uses your branch naming. +- Customize **issue templates** (copy, add fields, change labels) while keeping label and workflow names consistent as above. +- Add or modify **release/hotfix** workflow steps (e.g. build, deploy) while keeping the workflow **filenames** and the action inputs `release-workflow` and `hotfix-workflow` in sync. + +For a full list of inputs and behaviors, see [Configuration](/configuration) and [Features & capabilities](/features). diff --git a/docs/index.mdx b/docs/index.mdx index 4b659cea..79befb15 100644 --- a/docs/index.mdx +++ b/docs/index.mdx @@ -1,11 +1,13 @@ --- -title: Git-Board-Flow +title: Copilot description: Streamline your GitHub workflow with automated branch management, issue tracking, and project integration. Enhance team collaboration and optimize your development process. --- +export const Columns = ({ children }) =>
{children}
+ > This is Github with super powers 🚀 -**Git Board Flow** is designed with task management in mind, closely mirroring the approach used by Atlassian with Bitbucket and Jira. It leverages GitHub's project boards and issues as the foundation for task management at every stage of development. +**Copilot** is designed with task management in mind, closely mirroring the approach used by Atlassian with Bitbucket and Jira. It leverages GitHub's project boards and issues as the foundation for task management at every stage of development. The goal is to replicate the seamless integration of boards, tasks, and branches that Atlassian offers, enhancing your workflow and project management capabilities. @@ -13,7 +15,7 @@ This repository itself utilizes this GitHub Action for task management. You can Experience seamless project management, automated branch handling, and enhanced team collaboration. Start optimizing your development process today and take your Git workflow to the next level! ✨ - + Step-by-step setup for issues, pull requests, and push workflows. @@ -32,7 +34,7 @@ Experience seamless project management, automated branch handling, and enhanced Common issues and solutions. - + ## Motivation diff --git a/docs/issues/index.mdx b/docs/issues/index.mdx index 83c85635..40456515 100644 --- a/docs/issues/index.mdx +++ b/docs/issues/index.mdx @@ -3,7 +3,7 @@ title: Issues description: Boosted and connected issues. --- -Git Board Flow automates issue tracking, ensuring smooth branch management and seamless project integration. +Copilot automates issue tracking, ensuring smooth branch management and seamless project integration. ## Labels by issue type and flow @@ -27,7 +27,7 @@ For **step-by-step flows** (how branches are created, naming, source branch, dep To enable the GitHub Action for issues, create a workflow with the following configuration: ```yml -name: Git Board Flow - Issue +name: Copilot - Issue on: issues: @@ -39,7 +39,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: landamessenger/git-board-flow@master + - uses: vypdev/copilot@master with: project-ids: '1,2' token: ${{ secrets.PAT }} @@ -47,7 +47,7 @@ jobs: ### Member Assignment -Git Board Flow rolls the dice for you by automatically assigning newly created issues to a member of the organization or repository. +Copilot rolls the dice for you by automatically assigning newly created issues to a member of the organization or repository. @@ -59,7 +59,7 @@ Git Board Flow rolls the dice for you by automatically assigning newly created i name: Git Board - Issue runs-on: ubuntu-latest steps: - - uses: landamessenger/git-board-flow@v1 + - uses: vypdev/copilot@v1 with: desired-assignees-count: 1 // [!code highlight] ``` @@ -67,7 +67,7 @@ Git Board Flow rolls the dice for you by automatically assigning newly created i ### Board Assignment -Git Board Flow takes care of organizing your issues by automatically assigning newly created issues to a designated project board, ensuring seamless tracking and management. +Copilot takes care of organizing your issues by automatically assigning newly created issues to a designated project board, ensuring seamless tracking and management. Linking the issue to a board requires a Personal Access Token (PAT). @@ -81,7 +81,7 @@ Git Board Flow takes care of organizing your issues by automatically assigning n name: Git Board - Issue runs-on: ubuntu-latest steps: - - uses: landamessenger/git-board-flow@v1 + - uses: vypdev/copilot@v1 with: project-ids: 1, 2 // [!code highlight] ``` @@ -105,7 +105,7 @@ Some types of issues (`hotfix` and `release`) create branches automatically. Thi name: Git Board - Issue runs-on: ubuntu-latest steps: - - uses: landamessenger/git-board-flow@v1 + - uses: vypdev/copilot@v1 with: branch-management-launcher-label: branched // [!code highlight] ``` @@ -122,7 +122,7 @@ Some types of issues (`hotfix` and `release`) create branches automatically. Thi name: Git Board - Issue runs-on: ubuntu-latest steps: - - uses: landamessenger/git-board-flow@v1 + - uses: vypdev/copilot@v1 with: main-branch: master // [!code highlight] development-branch: develop // [!code highlight] @@ -137,17 +137,17 @@ Some types of issues (`hotfix` and `release`) create branches automatically. Thi ### Smart Workflow Guidance -Many developers are familiar with the Git-Flow methodology, but that doesn’t prevent mistakes from happening during the process of creating new features, maintaining code or documentation, fixing bugs, and deploying new versions. Git-Board-Flow will remind you of key steps to minimize these errors as much as possible. Even if you're not familiar with the Git-Flow methodology, you'll be able to manage branches easily and confidently. +Many developers are familiar with the Git-Flow methodology, but that doesn’t prevent mistakes from happening during the process of creating new features, maintaining code or documentation, fixing bugs, and deploying new versions. Copilot will remind you of key steps to minimize these errors as much as possible. Even if you're not familiar with the Git-Flow methodology, you'll be able to manage branches easily and confidently. ### Real-Time Code Tracking Issues take time to be resolved, and interest in their progress increases. Therefore, any changes in the branches created by the issue will be notified as comments, providing real-time feedback on the issue's progress. -### Bugbot (potential problems) {#bugbot-potential-problems} +### Bugbot (potential problems) When the **push** workflow runs (or you run the single action `detect_potential_problems_action` with `single-action-issue`), OpenCode analyzes the branch vs the base and reports potential problems (bugs, risks, improvements) as **comments on the issue**. Each finding appears as a comment with title, severity, and optional file/line. If a previously reported finding is later fixed, the action **updates** that comment (e.g. marks it as resolved) so the issue stays in sync. Findings are also posted as **review comments on open PRs** for the same branch; see [Pull Requests → Bugbot](/pull-requests#bugbot-potential-problems). You can set a minimum severity with `bugbot-severity` and exclude paths with `ai-ignore-files`; see [Configuration](/configuration). ### Auto-Closure -Forget about closing issues when development is complete, Git-Board-Flow will automatically close them once the branches created by the issue are successfully merged. +Forget about closing issues when development is complete, Copilot will automatically close them once the branches created by the issue are successfully merged. diff --git a/docs/issues/type/bugfix.mdx b/docs/issues/type/bugfix.mdx index 01aea6ff..22f1f318 100644 --- a/docs/issues/type/bugfix.mdx +++ b/docs/issues/type/bugfix.mdx @@ -15,7 +15,7 @@ jobs: name: Git Board - Issue runs-on: ubuntu-latest steps: - - uses: landamessenger/git-board-flow@v1 + - uses: vypdev/copilot@v1 with: bugfix-label: bugfix // [!code highlight] ``` @@ -30,7 +30,7 @@ jobs: name: Git Board - Issue runs-on: ubuntu-latest steps: - - uses: landamessenger/git-board-flow@v1 + - uses: vypdev/copilot@v1 with: bugfix-tree: bugfix // [!code highlight] ``` @@ -56,14 +56,14 @@ jobs: name: Git Board - Issue runs-on: ubuntu-latest steps: - - uses: landamessenger/git-board-flow@v1 + - uses: vypdev/copilot@v1 with: development-branch: develop // [!code highlight] ``` ## Images -You can configure custom images to be displayed in the comments of bugfix issues. These images will be randomly selected and displayed when Git Board Flow performs actions on the issue. +You can configure custom images to be displayed in the comments of bugfix issues. These images will be randomly selected and displayed when Copilot performs actions on the issue. To configure the images, provide a comma-separated list of image URLs in the `images-issue-bugfix` input: @@ -73,7 +73,7 @@ jobs: name: Git Board - Issue runs-on: ubuntu-latest steps: - - uses: landamessenger/git-board-flow@v1 + - uses: vypdev/copilot@v1 with: images-issue-bugfix: url1, url2, url3 // [!code highlight] ``` @@ -88,7 +88,7 @@ You can use this template for bugfix issues that helps capture all the necessary - Selecting affected actions and platforms - Providing a detailed bug description - Including steps to reproduce -- Specifying git-board-flow version +- Specifying copilot version - Adding relevant log output - Including additional context and comments @@ -96,7 +96,7 @@ You can find this template in `.github/ISSUE_TEMPLATE/bug_report.yml`. Below is ```yml name: 🐛 Bug Report -description: Report a bug on git-board-flow +description: Report a bug on copilot title: "" labels: ["bug", "bugfix"] body: @@ -165,8 +165,8 @@ body: - type: input attributes: - label: git-board-flow Version - description: What version of git-board-flow is being used? + label: copilot Version + description: What version of copilot is being used? placeholder: "master" validations: required: true diff --git a/docs/issues/type/chore.mdx b/docs/issues/type/chore.mdx index d9b24bc7..c1ac2773 100644 --- a/docs/issues/type/chore.mdx +++ b/docs/issues/type/chore.mdx @@ -15,7 +15,7 @@ jobs: name: Git Board - Issue runs-on: ubuntu-latest steps: - - uses: landamessenger/git-board-flow@v1 + - uses: vypdev/copilot@v1 with: chore-label: chore // [!code highlight] ``` @@ -30,7 +30,7 @@ jobs: name: Git Board - Issue runs-on: ubuntu-latest steps: - - uses: landamessenger/git-board-flow@v1 + - uses: vypdev/copilot@v1 with: chore-tree: chore // [!code highlight] ``` @@ -56,14 +56,14 @@ jobs: name: Git Board - Issue runs-on: ubuntu-latest steps: - - uses: landamessenger/git-board-flow@v1 + - uses: vypdev/copilot@v1 with: development-branch: develop // [!code highlight] ``` ## Images -You can configure custom images to be displayed in the comments of chore issues. These images will be randomly selected and displayed when Git Board Flow performs actions on the issue. +You can configure custom images to be displayed in the comments of chore issues. These images will be randomly selected and displayed when Copilot performs actions on the issue. To configure the images, provide a comma-separated list of image URLs in the `images-issue-chore` input: @@ -73,7 +73,7 @@ jobs: name: Git Board - Issue runs-on: ubuntu-latest steps: - - uses: landamessenger/git-board-flow@v1 + - uses: vypdev/copilot@v1 with: images-issue-chore: url1, url2, url3 // [!code highlight] ``` diff --git a/docs/issues/type/docs.mdx b/docs/issues/type/docs.mdx index 6967f0b6..66729f02 100644 --- a/docs/issues/type/docs.mdx +++ b/docs/issues/type/docs.mdx @@ -15,7 +15,7 @@ jobs: name: Git Board - Issue runs-on: ubuntu-latest steps: - - uses: landamessenger/git-board-flow@v1 + - uses: vypdev/copilot@v1 with: docs-label: docs // [!code highlight] ``` @@ -30,7 +30,7 @@ jobs: name: Git Board - Issue runs-on: ubuntu-latest steps: - - uses: landamessenger/git-board-flow@v1 + - uses: vypdev/copilot@v1 with: docs-tree: docs // [!code highlight] ``` @@ -56,14 +56,14 @@ jobs: name: Git Board - Issue runs-on: ubuntu-latest steps: - - uses: landamessenger/git-board-flow@v1 + - uses: vypdev/copilot@v1 with: development-branch: develop // [!code highlight] ``` ## Images -You can configure custom images to be displayed in the comments of documentation issues. These images will be randomly selected and displayed when Git Board Flow performs actions on the issue. +You can configure custom images to be displayed in the comments of documentation issues. These images will be randomly selected and displayed when Copilot performs actions on the issue. To configure the images, provide a comma-separated list of image URLs in the `images-issue-docs` input: @@ -73,7 +73,7 @@ jobs: name: Git Board - Issue runs-on: ubuntu-latest steps: - - uses: landamessenger/git-board-flow@v1 + - uses: vypdev/copilot@v1 with: images-issue-docs: url1, url2, url3 // [!code highlight] ``` diff --git a/docs/issues/type/feature.mdx b/docs/issues/type/feature.mdx index ff8eef0c..d18bdae3 100644 --- a/docs/issues/type/feature.mdx +++ b/docs/issues/type/feature.mdx @@ -15,7 +15,7 @@ jobs: name: Git Board - Issue runs-on: ubuntu-latest steps: - - uses: landamessenger/git-board-flow@v1 + - uses: vypdev/copilot@v1 with: feature-label: feature // [!code highlight] ``` @@ -30,7 +30,7 @@ jobs: name: Git Board - Issue runs-on: ubuntu-latest steps: - - uses: landamessenger/git-board-flow@v1 + - uses: vypdev/copilot@v1 with: feature-tree: feature // [!code highlight] ``` @@ -56,14 +56,14 @@ jobs: name: Git Board - Issue runs-on: ubuntu-latest steps: - - uses: landamessenger/git-board-flow@v1 + - uses: vypdev/copilot@v1 with: development-branch: develop // [!code highlight] ``` ## Images -You can configure custom images to be displayed in the comments of feature issues. These images will be randomly selected and displayed when Git Board Flow performs actions on the issue. +You can configure custom images to be displayed in the comments of feature issues. These images will be randomly selected and displayed when Copilot performs actions on the issue. To configure the images, provide a comma-separated list of image URLs in the `images-issue-feature` input: @@ -73,7 +73,7 @@ jobs: name: Git Board - Issue runs-on: ubuntu-latest steps: - - uses: landamessenger/git-board-flow@v1 + - uses: vypdev/copilot@v1 with: images-issue-feature: url1, url2, url3 // [!code highlight] ``` @@ -91,14 +91,14 @@ You can use this template for feature issues that helps capture all the necessar - Explaining current limitations and challenges - Describing expected impact and benefits - Considering alternative solutions -- Specifying git-board-flow version +- Specifying copilot version - Adding additional context and comments You can find this template in `.github/ISSUE_TEMPLATE/feature_request.yml`. Below is an example of how the template looks when creating a new feature issue: ```yml name: ✨ Feature Request -description: Propose an idea or improvement for git-board-flow +description: Propose an idea or improvement for copilot title: "" labels: ["enhancement", "feature"] body: @@ -191,9 +191,9 @@ body: - type: input attributes: - label: Version of git-board-flow + label: Version of copilot description: | - What version of git-board-flow are you using, or does this proposal apply to all versions? + What version of copilot are you using, or does this proposal apply to all versions? placeholder: "master" validations: required: false diff --git a/docs/issues/type/hotfix.mdx b/docs/issues/type/hotfix.mdx index 78e1e21a..cf18cb60 100644 --- a/docs/issues/type/hotfix.mdx +++ b/docs/issues/type/hotfix.mdx @@ -50,7 +50,7 @@ This workflow ensures that critical fixes reach production quickly while maintai name: Git Board - Issue runs-on: ubuntu-latest steps: - - uses: landamessenger/git-board-flow@v1 + - uses: vypdev/copilot@v1 with: deploy-label: deploy // [!code highlight] hotfix-workflow: hotfix_workflow.yml // [!code highlight] @@ -104,7 +104,7 @@ This workflow ensures that critical fixes reach production quickly while maintai // deploy logic here - name: Git Board - Deploy success notification - uses: landamessenger/git-board-flow@v1 + uses: vypdev/copilot@v1 if: ${{ success() }} with: single-action: 'deployed_action' @@ -134,7 +134,7 @@ jobs: name: Git Board - Issue runs-on: ubuntu-latest steps: - - uses: landamessenger/git-board-flow@v1 + - uses: vypdev/copilot@v1 with: hotfix-label: hotfix // [!code highlight] ``` @@ -149,7 +149,7 @@ jobs: name: Git Board - Issue runs-on: ubuntu-latest steps: - - uses: landamessenger/git-board-flow@v1 + - uses: vypdev/copilot@v1 with: hotfix-tree: hotfix // [!code highlight] ``` @@ -175,14 +175,14 @@ jobs: name: Git Board - Issue runs-on: ubuntu-latest steps: - - uses: landamessenger/git-board-flow@v1 + - uses: vypdev/copilot@v1 with: main-branch: master // [!code highlight] ``` ## Images -You can configure custom images to be displayed in the comments of hotfix issues. These images will be randomly selected and displayed when Git Board Flow performs actions on the issue. +You can configure custom images to be displayed in the comments of hotfix issues. These images will be randomly selected and displayed when Copilot performs actions on the issue. To configure the images, provide a comma-separated list of image URLs in the `images-issue-hotfix` input: @@ -192,7 +192,7 @@ jobs: name: Git Board - Issue runs-on: ubuntu-latest steps: - - uses: landamessenger/git-board-flow@v1 + - uses: vypdev/copilot@v1 with: images-issue-hotfix: url1, url2, url3 // [!code highlight] ``` @@ -213,7 +213,7 @@ You can find this template in `.github/ISSUE_TEMPLATE/hotfix.yml`. Below is an e ```yml name: 🔥 Hotfix Issue -description: Request a new hotfix for git-board-flow (only team members) +description: Request a new hotfix for copilot (only team members) title: "" labels: [ "hotfix", "branched" ] body: @@ -221,7 +221,7 @@ body: attributes: value: | ### ⚠️ Disclaimer - > **Only members of the git-board-flow team can create hotfix issues.** + > **Only members of the copilot team can create hotfix issues.** > Any hotfix issue created by someone outside the team will be closed automatically. --- diff --git a/docs/issues/type/release.mdx b/docs/issues/type/release.mdx index 94b6f330..c664318a 100644 --- a/docs/issues/type/release.mdx +++ b/docs/issues/type/release.mdx @@ -50,7 +50,7 @@ This workflow ensures that releases are properly planned, tested, and deployed w name: Git Board - Issue runs-on: ubuntu-latest steps: - - uses: landamessenger/git-board-flow@v1 + - uses: vypdev/copilot@v1 with: deploy-label: deploy // [!code highlight] release-workflow: release_workflow.yml // [!code highlight] @@ -104,7 +104,7 @@ This workflow ensures that releases are properly planned, tested, and deployed w // deploy logic here - name: Git Board - Deploy success notification - uses: landamessenger/git-board-flow@v1 + uses: vypdev/copilot@v1 if: ${{ success() }} with: single-action: 'deployed_action' @@ -134,7 +134,7 @@ jobs: name: Git Board - Issue runs-on: ubuntu-latest steps: - - uses: landamessenger/git-board-flow@v1 + - uses: vypdev/copilot@v1 with: release-label: release // [!code highlight] ``` @@ -149,7 +149,7 @@ jobs: name: Git Board - Issue runs-on: ubuntu-latest steps: - - uses: landamessenger/git-board-flow@v1 + - uses: vypdev/copilot@v1 with: release-tree: release // [!code highlight] ``` @@ -175,14 +175,14 @@ jobs: name: Git Board - Issue runs-on: ubuntu-latest steps: - - uses: landamessenger/git-board-flow@v1 + - uses: vypdev/copilot@v1 with: development-branch: development // [!code highlight] ``` ## Images -You can configure custom images to be displayed in the comments of release issues. These images will be randomly selected and displayed when Git Board Flow performs actions on the issue. +You can configure custom images to be displayed in the comments of release issues. These images will be randomly selected and displayed when Copilot performs actions on the issue. To configure the images, provide a comma-separated list of image URLs in the `images-issue-release` input: @@ -192,7 +192,7 @@ jobs: name: Git Board - Issue runs-on: ubuntu-latest steps: - - uses: landamessenger/git-board-flow@v1 + - uses: vypdev/copilot@v1 with: images-issue-release: url1, url2, url3 // [!code highlight] ``` @@ -211,7 +211,7 @@ You can find this template in `.github/ISSUE_TEMPLATE/release.yml`. Below is an ```yml name: 🚀 Release Issue -description: Request a new release for git-board-flow (only team members) +description: Request a new release for copilot (only team members) title: "" labels: ["release", "branched"] body: @@ -219,7 +219,7 @@ body: attributes: value: | ### ⚠️ Disclaimer - > **Only members of the git-board-flow team can create release issues.** + > **Only members of the copilot team can create release issues.** > Any release issue created by someone outside the team will be closed automatically. --- diff --git a/docs/opencode-integration.mdx b/docs/opencode-integration.mdx index c3973412..bb73a98a 100644 --- a/docs/opencode-integration.mdx +++ b/docs/opencode-integration.mdx @@ -1,11 +1,11 @@ --- title: OpenCode (AI) -description: Configure OpenCode for all AI features in Git Board Flow +description: Configure OpenCode for all AI features in Copilot --- # OpenCode Integration -Git Board Flow uses **OpenCode** for all AI-backed features: code analysis, progress detection, error detection, PR descriptions, and the copilot agent. OpenRouter has been removed in favor of OpenCode. +Copilot uses **OpenCode** for all AI-backed features: code analysis, progress detection, error detection, PR descriptions, and the copilot agent. OpenRouter has been removed in favor of OpenCode. ## Why OpenCode @@ -118,7 +118,7 @@ Then set `opencode-model: 'ollama/llama2'` (or the model ID you defined). See [O Set the variables for the provider you use in the workflow `env`. Only one primary provider is needed for the model you choose: ```yaml -- uses: landamessenger/git-board-flow@master +- uses: vypdev/copilot@master env: # Option A: Anthropic ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} @@ -150,7 +150,7 @@ For the full list of providers and any new env var names, see the official [Open Example (using your own OpenCode server): ```yaml -- uses: landamessenger/git-board-flow@master +- uses: vypdev/copilot@master with: opencode-server-url: 'http://your-opencode-host:4096' opencode-model: 'anthropic/claude-3-5-sonnet' @@ -159,7 +159,7 @@ Example (using your own OpenCode server): Example (action starts and stops OpenCode for you; no separate server needed). Set the provider API key in `env` using the variable name OpenCode expects (e.g. `OPENAI_API_KEY`, `ANTHROPIC_API_KEY`, or `OPENROUTER_API_KEY`): ```yaml -- uses: landamessenger/git-board-flow@master +- uses: vypdev/copilot@master env: ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} # or OPENAI_API_KEY, OPENROUTER_API_KEY, etc. with: diff --git a/docs/pull-requests/ai-description.mdx b/docs/pull-requests/ai-description.mdx index d4c77fa8..ba07ea7f 100644 --- a/docs/pull-requests/ai-description.mdx +++ b/docs/pull-requests/ai-description.mdx @@ -27,9 +27,9 @@ The AI is instructed to use your repository's **pull request template** as the s If you don't have a template, the agent will still produce a structured description, but defining a template ensures consistent, professional PR descriptions that match your team's expectations (e.g. Summary, Related Issues, Scope of Changes, Technical Details, How to Test, Breaking Changes, Deployment Notes, etc.). - + **Recommendation:** Add a `.github/pull_request_template.md` in your repo with the sections you want (summary, scope, testing, breaking changes, etc.). The AI will use it as a guide and fill it with the information from the issue and the branch diff. - + ## When the AI description runs @@ -45,7 +45,7 @@ If you don't have a template, the agent will still produce a structured descript Set `ai-pull-request-description: true` and configure OpenCode in your workflow: ```yaml -- uses: landamessenger/git-board-flow@master +- uses: vypdev/copilot@master with: token: ${{ secrets.PAT }} project-ids: '2,3' diff --git a/docs/pull-requests/index.mdx b/docs/pull-requests/index.mdx index 5faa7012..7bfacb28 100644 --- a/docs/pull-requests/index.mdx +++ b/docs/pull-requests/index.mdx @@ -1,30 +1,30 @@ --- title: Pull Requests -description: How Git Board Flow handles pull requests +description: How Copilot handles pull requests --- # Pull Request Management -When your workflow runs on `pull_request` events (e.g. opened, edited, labeled, unlabeled), Git Board Flow performs a set of actions so that PRs stay linked to issues, projects, and team workflows. +When your workflow runs on `pull_request` events (e.g. opened, edited, labeled, unlabeled), Copilot performs a set of actions so that PRs stay linked to issues, projects, and team workflows. ## Enable the action for pull requests -Create a workflow file (e.g. `.github/workflows/gbf_pull_request.yml`) that runs on `pull_request`: +Create a workflow file (e.g. `.github/workflows/copilot_pull_request.yml`) that runs on `pull_request`: ```yaml -name: Git Board Flow - Pull Request +name: Copilot - Pull Request on: pull_request: types: [opened, edited, labeled, unlabeled] jobs: - git-board-flow-pull-requests: - name: Git Board Flow - Pull Request + copilot-pull-requests: + name: Copilot - Pull Request runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: landamessenger/git-board-flow@master + - uses: vypdev/copilot@master with: token: ${{ secrets.PAT }} project-ids: '2,3' @@ -46,7 +46,7 @@ jobs: | **AI-generated PR description** | When enabled, generates or updates the PR description using OpenCode and your repo's PR template. See [AI PR description](/pull-requests/ai-description). | | **Comments & images** | Posts a comment with optional images per branch type (feature, bugfix, docs, chore, hotfix, release). | -## Bugbot (potential problems) {#bugbot-potential-problems} +## Bugbot (potential problems) When the **push** workflow runs (or the single action `detect_potential_problems_action`), OpenCode analyzes the branch vs the base and posts **review comments** on the PR at the relevant file and line for each finding (potential bugs, risks, or improvements). When OpenCode later reports a finding as resolved (e.g. after code changes), the action **marks that review thread as resolved**, so the PR review reflects the current status. Findings are also summarized as **comments on the linked issue**; see [Issues → Bugbot](/issues#bugbot-potential-problems). Configure minimum severity with `bugbot-severity` and excluded paths with `ai-ignore-files` in [Configuration](/configuration). diff --git a/docs/single-actions/configuration.mdx b/docs/single-actions/configuration.mdx index 736e55b8..628c9918 100644 --- a/docs/single-actions/configuration.mdx +++ b/docs/single-actions/configuration.mdx @@ -1,6 +1,6 @@ --- title: Single Actions Configuration -description: Inputs for running single actions in Git Board Flow +description: Inputs for running single actions in Copilot --- # Single Actions Configuration @@ -40,7 +40,7 @@ For **`create_release`** only: ## Example: workflow with single action ```yaml -- uses: landamessenger/git-board-flow@master +- uses: vypdev/copilot@master with: token: ${{ secrets.PAT }} single-action: check_progress_action @@ -50,7 +50,7 @@ For **`create_release`** only: For release: ```yaml -- uses: landamessenger/git-board-flow@master +- uses: vypdev/copilot@master with: token: ${{ secrets.PAT }} single-action: create_release diff --git a/docs/single-actions/index.mdx b/docs/single-actions/index.mdx index a409e6ff..550c7573 100644 --- a/docs/single-actions/index.mdx +++ b/docs/single-actions/index.mdx @@ -5,7 +5,7 @@ description: Run one-off actions on demand (check progress, think, create releas # Single Actions -When you set the `single-action` input (and any required targets such as `single-action-issue` or `single-action-version`), Git Board Flow runs **only** that action and skips the normal issue, pull request, and push pipelines. +When you set the `single-action` input (and any required targets such as `single-action-issue` or `single-action-version`), Copilot runs **only** that action and skips the normal issue, pull request, and push pipelines. ## Available single actions @@ -21,9 +21,9 @@ When you set the `single-action` input (and any required targets such as `single | `publish_github_action` | — | Publishes or updates the GitHub Action (e.g. versioning, release). | | `deployed_action` | `single-action-issue` | Marks the issue as deployed; updates labels and project state. | - + **Actions that fail the job** if the last step fails: `publish_github_action`, `create_release`, `deployed_action`, `create_tag`. The workflow will be marked as failed so you can act on it. - + ## Next steps diff --git a/docs/single-actions/workflow-and-cli.mdx b/docs/single-actions/workflow-and-cli.mdx index 9414eef9..602b4e4e 100644 --- a/docs/single-actions/workflow-and-cli.mdx +++ b/docs/single-actions/workflow-and-cli.mdx @@ -17,7 +17,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: landamessenger/git-board-flow@master + - uses: vypdev/copilot@master with: token: ${{ secrets.PAT }} single-action: check_progress_action @@ -28,7 +28,7 @@ Use `workflow_dispatch` to run on demand, or trigger from another event. See [Co ## From the CLI (`giik`) -Build the CLI from the git-board-flow repo, then run it from **any repo** that has `origin` pointing to GitHub (or from the same repo): +Build the CLI from the copilot repo, then run it from **any repo** that has `origin` pointing to GitHub (or from the same repo): ```bash nvm use 20 diff --git a/docs/support.mdx b/docs/support.mdx index 1a3a4449..0eb7006d 100644 --- a/docs/support.mdx +++ b/docs/support.mdx @@ -1,16 +1,16 @@ --- title: Support -description: Getting help and contributing to Git Board Flow +description: Getting help and contributing to Copilot --- # Support -Learn how to get help with Git Board Flow and contribute to its development. +Learn how to get help with Copilot and contribute to its development. ## Getting Help ### Documentation -- Review the [documentation](https://docs.page/landamessenger/git-board-flow) +- Review the [documentation](https://docs.page/vypdev/copilot) - Check the [configuration guide](/configuration) and [Features & Capabilities](/features) ### Issue Reporting @@ -19,7 +19,7 @@ When reporting issues, follow these steps: - Check [existing issues](https://github.com/landamessenger/git-board-flow/issues) to avoid duplicates. + Check [existing issues](https://github.com/vypdev/copilot/issues) to avoid duplicates. - Detailed description @@ -32,7 +32,7 @@ When reporting issues, follow these steps: ### Community Support - Use GitHub Discussions for questions -- Check Stack Overflow with tag `git-board-flow` +- Check Stack Overflow with tag `copilot` - Join our community channels ## Contributing @@ -49,7 +49,7 @@ When reporting issues, follow these steps: ```bash # Clone the repository -git clone https://github.com/landamessenger/git-board-flow.git +git clone https://github.com/vypdev/copilot.git # Install dependencies npm install @@ -90,15 +90,14 @@ For security issues: ## Stay Updated -- Watch the [GitHub repository](https://github.com/landamessenger/git-board-flow) +- Watch the [GitHub repository](https://github.com/vypdev/copilot) - Follow release announcements - Join our mailing list - Check our blog for updates ## Contact -- GitHub Issues: [Report a bug](https://github.com/landamessenger/git-board-flow/issues) -- Email: support@gitboardflow.com -- Twitter: [@GitBoardFlow](https://twitter.com/gitboardflow) +- GitHub Issues: [Report a bug](https://github.com/vypdev/copilot/issues) +- Email: efraespada@vyp.dev We aim to respond to all inquiries within 48 hours during business days. \ No newline at end of file diff --git a/docs/testing-opencode-plan-locally.mdx b/docs/testing-opencode-plan-locally.mdx index c91e280a..ac8c6d17 100644 --- a/docs/testing-opencode-plan-locally.mdx +++ b/docs/testing-opencode-plan-locally.mdx @@ -5,7 +5,7 @@ description: Step-by-step guide to test check-progress, detect-potential-problem # Testing OpenCode Plan Locally -This guide walks you through testing the OpenCode Plan flows (`check-progress`, `detect-potential-problems`, `recommend-steps`) locally using the `giik` CLI, without running GitHub Actions. +This guide walks you through testing the OpenCode Plan flows (`check-progress`, `detect-potential-problems`, `recommend-steps`) locally using the `copilot` CLI, without running GitHub Actions. ## Prerequisites @@ -28,7 +28,7 @@ Ensure the server is healthy before running the CLI. The default URL is `http:// ## 2. Build the CLI -From the git-board-flow repository root: +From the copilot repository root: ```bash nvm use 20 @@ -77,9 +77,9 @@ node build/cli/index.js recommend-steps -i -t ## 4. Optional: .env File - + You can store your token and OpenCode settings in a `.env` file so you don't need to pass `-t` and OpenCode options every time. - + Create a `.env` file in the repo root (do **not** commit it): diff --git a/docs/troubleshooting.mdx b/docs/troubleshooting.mdx index 1f8d0d8a..21928e4a 100644 --- a/docs/troubleshooting.mdx +++ b/docs/troubleshooting.mdx @@ -1,11 +1,11 @@ --- title: Troubleshooting -description: Common issues and solutions when using Git Board Flow +description: Common issues and solutions when using Copilot --- # Troubleshooting -This guide helps you resolve common issues you might encounter while using Git Board Flow. Expand the section that matches your problem. +This guide helps you resolve common issues you might encounter while using Copilot. Expand the section that matches your problem. @@ -81,7 +81,7 @@ This guide helps you resolve common issues you might encounter while using Git B If you're still experiencing issues: - 1. Check the [GitHub repository](https://github.com/landamessenger/git-board-flow) for known issues. + 1. Check the [GitHub repository](https://github.com/vypdev/copilot) for known issues. 2. Review the latest documentation. 3. Open a new issue with: - Detailed description diff --git a/package-lock.json b/package-lock.json index 983282d7..f64d8ede 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,11 +1,11 @@ { - "name": "git-board-flow", + "name": "copilot", "version": "1.3.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "git-board-flow", + "name": "copilot", "version": "1.3.0", "license": "ISC", "dependencies": { @@ -27,7 +27,7 @@ "js-yaml": "^4.1.0" }, "bin": { - "giik": "build/cli/index.js" + "copilot": "build/cli/index.js" }, "devDependencies": { "@eslint/js": "^9.15.0", diff --git a/package.json b/package.json index fe4539bc..d762b103 100644 --- a/package.json +++ b/package.json @@ -1,10 +1,10 @@ { - "name": "git-board-flow", + "name": "copilot", "version": "1.3.0", "description": "Automates branch management, GitHub project linking, and issue/PR tracking with Git-Flow methodology.", "main": "build/github_action/index.js", "bin": { - "giik": "./build/cli/index.js" + "copilot": "./build/cli/index.js" }, "scripts": { "build": "ncc build src/actions/github_action.ts -o build/github_action && ncc build src/cli.ts -o build/cli && chmod +x build/cli/index.js", @@ -12,10 +12,11 @@ "test:watch": "jest --watch", "test:coverage": "jest --coverage", "lint": "eslint src", - "lint:fix": "eslint src --fix" + "lint:fix": "eslint src --fix", + "postinstall": "node scripts/install-git-hooks.cjs" }, "keywords": [], - "author": "Landa Messenger", + "author": "Efra Espada", "license": "ISC", "dependencies": { "@actions/cache": "^4.0.3", diff --git a/scripts/git-hooks/pre-commit b/scripts/git-hooks/pre-commit new file mode 100644 index 00000000..4c1f675f --- /dev/null +++ b/scripts/git-hooks/pre-commit @@ -0,0 +1,5 @@ +#!/bin/sh +# Pre-commit launcher: runs the Node script from the repo. +# On Windows: Git for Windows runs hooks with Bash, so this script runs there too. +ROOT=$(git rev-parse --show-toplevel) +exec node "$ROOT/scripts/git-hooks/pre-commit.cjs" diff --git a/scripts/git-hooks/pre-commit.cjs b/scripts/git-hooks/pre-commit.cjs new file mode 100644 index 00000000..168fe8b6 --- /dev/null +++ b/scripts/git-hooks/pre-commit.cjs @@ -0,0 +1,22 @@ +/** + * Pre-commit hook: run build, test, and lint before allowing a commit. + * Cross-platform (Windows, macOS, Linux). Invoked by the pre-commit shell launcher. + * On Windows, Git for Windows runs the launcher with Bash, which then runs this script with Node. + */ + +const { spawnSync } = require('child_process'); +const path = require('path'); + +const root = path.resolve(__dirname, '..', '..'); +const opts = { cwd: root, stdio: 'inherit', shell: true }; // shell: true so "npm" works on Windows (npm.cmd) + +function run(name, args) { + const r = spawnSync(name, args, opts); + if (r.status !== 0) { + process.exit(r.status); + } +} + +run('npm', ['run', 'build']); +run('npm', ['test']); +run('npm', ['run', 'lint']); diff --git a/scripts/git-hooks/prepare-commit-msg b/scripts/git-hooks/prepare-commit-msg new file mode 100644 index 00000000..df96c12e --- /dev/null +++ b/scripts/git-hooks/prepare-commit-msg @@ -0,0 +1,5 @@ +#!/bin/sh +# Launcher for prepare-commit-msg: runs the Node script from the repo. +# On Windows: Git for Windows runs hooks with Bash, so this script runs there too. +ROOT=$(git rev-parse --show-toplevel) +exec node "$ROOT/scripts/git-hooks/prepare-commit-msg.cjs" "$@" diff --git a/scripts/git-hooks/prepare-commit-msg.cjs b/scripts/git-hooks/prepare-commit-msg.cjs new file mode 100644 index 00000000..f2f23e31 --- /dev/null +++ b/scripts/git-hooks/prepare-commit-msg.cjs @@ -0,0 +1,39 @@ +/** + * Ensures the commit message starts with the current branch name (with / replaced by -). + * Strips any existing prefix so the correct one is always applied. + * Cross-platform (Windows, macOS, Linux). Invoked by the prepare-commit-msg shell launcher. + */ + +const fs = require('fs'); +const path = require('path'); +const { spawnSync } = require('child_process'); + +const msgFile = process.argv[2]; +const source = process.argv[3]; + +if (!msgFile || !fs.existsSync(msgFile) || !fs.statSync(msgFile).isFile()) { + process.exit(0); +} + +if (source === 'merge' || source === 'squash') { + process.exit(0); +} + +const root = path.resolve(__dirname, '..', '..'); +const r = spawnSync('git', ['branch', '--show-current'], { cwd: root, encoding: 'utf8' }); +const branch = (r.stdout && r.stdout.trim()) || ''; +if (!branch) process.exit(0); + +const prefix = branch.replace(/\//g, '-'); + +const content = fs.readFileSync(msgFile, 'utf8'); +const lines = content.split(/\r?\n/); +const firstLine = lines[0] || ''; +if (!firstLine.trim()) process.exit(0); + +const match = firstLine.match(/^[^:]+:\s*(.+)$/); +const body = match ? match[1] : firstLine; +const rest = lines.slice(1).join('\n'); + +const newContent = rest ? `${prefix}: ${body}\n${rest}` : `${prefix}: ${body}\n`; +fs.writeFileSync(msgFile, newContent, 'utf8'); diff --git a/scripts/install-git-hooks.cjs b/scripts/install-git-hooks.cjs new file mode 100644 index 00000000..ac88fe46 --- /dev/null +++ b/scripts/install-git-hooks.cjs @@ -0,0 +1,36 @@ +/** + * Installs git hooks from scripts/git-hooks/ into .git/hooks/. + * Cross-platform: Windows, macOS, Linux. + * Run automatically on npm install, or: node scripts/install-git-hooks.cjs + */ + +const fs = require('fs'); +const path = require('path'); + +const root = path.resolve(__dirname, '..'); +const hooksSrc = path.join(root, 'scripts', 'git-hooks'); +const hooksDst = path.join(root, '.git', 'hooks'); + +if (!fs.existsSync(path.join(root, '.git')) || !fs.statSync(path.join(root, '.git')).isDirectory()) { + process.exit(0); +} +if (!fs.existsSync(hooksSrc) || !fs.statSync(hooksSrc).isDirectory()) { + process.exit(0); +} +if (!fs.existsSync(hooksDst) || !fs.statSync(hooksDst).isDirectory()) { + process.exit(0); +} + +const files = fs.readdirSync(hooksSrc); +for (const name of files) { + const src = path.join(hooksSrc, name); + if (!fs.statSync(src).isFile()) continue; + const dst = path.join(hooksDst, name); + fs.copyFileSync(src, dst); + try { + fs.chmodSync(dst, 0o755); + } catch (_) { + // Windows: chmod may not support execute; Git for Windows still runs the hook + } + console.log('Installed hook: ' + name); +} diff --git a/setup/.env b/setup/.env new file mode 100644 index 00000000..cf1aca70 --- /dev/null +++ b/setup/.env @@ -0,0 +1 @@ +PERSONAL_ACCESS_TOKEN= diff --git a/setup/ISSUE_TEMPLATE/bug_report.yml b/setup/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 00000000..bf9b1c7c --- /dev/null +++ b/setup/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,100 @@ +name: 🐛 Bug Report +description: Report a bug on copilot +title: "" +labels: ["bug", "bugfix", "priority: high"] +body: + - type: checkboxes + attributes: + label: Is there an existing issue for this? + description: | + Please search to see if an issue already exists for the bug you encountered. + options: + - label: I have searched the existing issues. + required: true + + - type: markdown + attributes: + value: | + --- + + - type: dropdown + id: plugins + attributes: + label: Which actions are affected? + multiple: true + options: + - Issue + - Pull Request + - Commits + + - type: dropdown + id: platforms + attributes: + label: Which platforms are affected? + multiple: true + options: + - macOS + - Windows + - Linux + + - type: markdown + attributes: + value: | + --- + + - type: textarea + attributes: + label: Description + description: | + Describe the issue. Explain what you _expected_ to happen and what + _actually_ happened. + validations: + required: true + + - type: textarea + attributes: + label: Reproducing the issue + description: | + Please provide either **steps to reproduce** or a [**minimal reproducible example**](https://stackoverflow.com/help/minimal-reproducible-example). + Providing a minimal reproducible example will help us triage your issue + faster. + validations: + required: true + + - type: markdown + attributes: + value: | + --- + + - type: input + attributes: + label: copilot Version + description: What version of copilot is being used? + placeholder: "master" + validations: + required: true + + - type: markdown + attributes: + value: | + --- + + - type: textarea + attributes: + label: Relevant Log Output + description: | + Please copy and paste any relevant log output. + placeholder: | + Paste your logs here. Please redact any personally identifiable + information. This will be automatically formatted into code, so no + need for backticks. + render: shell + validations: + required: false + + - type: textarea + id: comments + attributes: + label: Additional context and comments + description: | + Anything else you want to add for this issue? \ No newline at end of file diff --git a/setup/ISSUE_TEMPLATE/chore_task.yml b/setup/ISSUE_TEMPLATE/chore_task.yml new file mode 100644 index 00000000..c50e534f --- /dev/null +++ b/setup/ISSUE_TEMPLATE/chore_task.yml @@ -0,0 +1,79 @@ +name: 🔧 Chore Task +description: Suggest a maintenance or internal improvement task +title: "" +labels: ["chore", "maintenance", "priority: low"] +body: + - type: checkboxes + attributes: + label: Is there an existing issue for this? + description: | + Please search to see if an issue already exists for what you are proposing. + options: + - label: I have searched the existing issues. + required: true + + - type: markdown + attributes: + value: | + --- + + - type: dropdown + id: chore_scope + attributes: + label: What area does this task affect? + multiple: false + options: + - CI/CD + - Dependencies + - Code Refactoring + - Repository Configuration + - Other + + - type: markdown + attributes: + value: | + --- + + - type: textarea + attributes: + label: Task description + description: | + Describe the chore task in detail. Explain what needs to be done and why. + validations: + required: true + + - type: textarea + attributes: + label: Current issues or inefficiencies + description: | + Describe any problems this task is addressing. Why is this necessary? + validations: + required: true + + - type: textarea + attributes: + label: Expected impact + description: | + Explain how completing this chore will improve the project. + validations: + required: true + + - type: textarea + attributes: + label: Alternatives considered + description: | + If you considered alternative solutions, describe them here. + validations: + required: false + + - type: markdown + attributes: + value: | + --- + + - type: textarea + id: comments + attributes: + label: Additional context or comments + description: | + Add any additional context, logs, or examples related to this task. diff --git a/setup/ISSUE_TEMPLATE/config.yml b/setup/ISSUE_TEMPLATE/config.yml new file mode 100644 index 00000000..5be8308c --- /dev/null +++ b/setup/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,5 @@ +blank_issues_enabled: false +contact_links: + - name: Git-Flow + url: https://nvie.com/posts/a-successful-git-branching-model/ + about: Check the original article by Vincent Driessen about git-flow before opening new issues. \ No newline at end of file diff --git a/setup/ISSUE_TEMPLATE/doc_update.yml b/setup/ISSUE_TEMPLATE/doc_update.yml new file mode 100644 index 00000000..a207b079 --- /dev/null +++ b/setup/ISSUE_TEMPLATE/doc_update.yml @@ -0,0 +1,71 @@ +name: 📝 Documentation Update +description: Propose changes or improvements to the documentation +title: "" +labels: ["documentation", "docs", "priority: low"] +body: + - type: checkboxes + attributes: + label: Is there an existing issue for this? + description: | + Please search to see if an issue already exists for what you are proposing. + options: + - label: I have searched the existing issues. + required: true + + - type: markdown + attributes: + value: | + --- + + - type: dropdown + id: docs_scope + attributes: + label: What part of the documentation needs an update? + multiple: false + options: + - README.md + - Wiki + - API Documentation + - Inline Code Comments + - Other + + - type: markdown + attributes: + value: | + --- + + - type: textarea + attributes: + label: Describe the documentation update + description: | + Provide a clear and detailed explanation of what should be updated or added. + validations: + required: true + + - type: textarea + attributes: + label: Why is this update needed? + description: | + Explain what issues or gaps this update is addressing. + validations: + required: true + + - type: textarea + attributes: + label: Additional resources + description: | + If you have any external links, references, or examples, include them here. + validations: + required: false + + - type: markdown + attributes: + value: | + --- + + - type: textarea + id: comments + attributes: + label: Additional context or comments + description: | + Add any additional context or suggestions related to this documentation update. diff --git a/setup/ISSUE_TEMPLATE/feature_request.yml b/setup/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 00000000..df7bf8e7 --- /dev/null +++ b/setup/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,113 @@ +name: ✨ Feature Request +description: Propose an idea or improvement for copilot +title: "" +labels: ["enhancement", "feature", "priority: low"] +body: + - type: checkboxes + attributes: + label: Is there an existing issue or feature request for this? + description: | + Please search to see if an issue or feature request already exists for what you are proposing. + options: + - label: I have searched the existing issues and feature requests. + required: true + + - type: markdown + attributes: + value: | + --- + + - type: dropdown + id: feature_scope + attributes: + label: What area does this improvement affect? + multiple: false + options: + - User Interface + - Performance + - New Feature + - Documentation + - Other + + - type: dropdown + id: feature_actions + attributes: + label: What actions does this improvement affect? + multiple: true + options: + - Issue + - Pull Request + - Commit + + - type: markdown + attributes: + value: | + --- + + - type: textarea + attributes: + label: Description of the idea or improvement + description: | + Describe your proposed idea or improvement in detail. Explain what you + would like to see and why it matters. + validations: + required: true + + - type: textarea + attributes: + label: Current limitations or challenges + description: | + Explain what problems or challenges this improvement would address. + Why is the current functionality insufficient? + validations: + required: true + + - type: markdown + attributes: + value: | + --- + + - type: textarea + attributes: + label: Expected impact + description: | + Describe how this improvement would benefit users or developers. + Include specific scenarios or use cases where this would make a difference. + validations: + required: true + + - type: textarea + attributes: + label: Alternatives considered + description: | + If you have considered alternative solutions or approaches, describe them here. + Why do you think your proposal is the best option? + validations: + required: false + + - type: markdown + attributes: + value: | + --- + + - type: input + attributes: + label: Version of copilot + description: | + What version of copilot are you using, or does this proposal apply to all versions? + placeholder: "master" + validations: + required: false + + - type: markdown + attributes: + value: | + --- + + - type: textarea + id: comments + attributes: + label: Additional context or comments + description: | + Add any additional context, screenshots, or examples that may help us + understand your proposal better. diff --git a/setup/ISSUE_TEMPLATE/help_request.yml b/setup/ISSUE_TEMPLATE/help_request.yml new file mode 100644 index 00000000..9f9a3dd0 --- /dev/null +++ b/setup/ISSUE_TEMPLATE/help_request.yml @@ -0,0 +1,72 @@ +name: 🙋 Help Request +description: Ask for help, guidance, or clarification about something in the project +title: "" +labels: ["help", "question", "priority: medium"] +body: + - type: checkboxes + attributes: + label: Have you checked for existing help or discussions? + description: | + Please make sure no one else has already asked this question or opened a similar issue. + options: + - label: I have searched existing issues and discussions. + required: true + + - type: markdown + attributes: + value: | + --- + + - type: dropdown + id: help_area + attributes: + label: What area do you need help with? + multiple: false + options: + - Code or implementation + - Build or setup + - Documentation or usage + - Workflow or CI/CD + - Other + + - type: markdown + attributes: + value: | + --- + + - type: textarea + attributes: + label: Describe your problem or question + description: | + Clearly describe what you need help with. Include context, what you've tried, and what you expected to happen. + validations: + required: true + + - type: textarea + attributes: + label: Steps or attempts you've already made + description: | + Describe what you’ve already tried to solve this problem. This helps others avoid suggesting the same things. + validations: + required: false + + - type: textarea + attributes: + label: Environment or context + description: | + Provide details such as OS, version, branch, or any relevant environment information. + validations: + required: false + + - type: textarea + attributes: + label: Additional context or screenshots + description: | + If applicable, add screenshots, logs, or any extra information that may help others understand the issue. + validations: + required: false + + - type: markdown + attributes: + value: | + --- diff --git a/setup/ISSUE_TEMPLATE/hotfix.yml b/setup/ISSUE_TEMPLATE/hotfix.yml new file mode 100644 index 00000000..618ca772 --- /dev/null +++ b/setup/ISSUE_TEMPLATE/hotfix.yml @@ -0,0 +1,64 @@ +name: 🔥 Hotfix Issue + +description: Request a new hotfix for copilot (only team members) +title: "" +labels: [ "hotfix", "branched", "priority: high" ] +body: + - type: markdown + attributes: + value: | + ### ⚠️ Disclaimer + > **Only members of the copilot team can create hotfix issues.** + > Any hotfix issue created by someone outside the team will be closed automatically. + + --- + + - type: input + id: base_version + attributes: + label: Base Version + description: | + The base version is typically the most recent tag version. However, you can specify a different version tag if you'd like to start from a specific version for this hotfix. + placeholder: "e.g., 1.2.3" + value: "Automatic" + validations: + required: false + + - type: input + id: hotfix_version + attributes: + label: Hotfix Version + description: | + By default, the version will increment the patch number of the most recent tag version (e.g., from 1.2.3 to 1.2.4). You can specify a different version number for the hotfix if needed. + placeholder: "e.g., 1.2.4" + value: "Automatic" + validations: + required: false + + - type: textarea + id: issue_description + attributes: + label: Issue Description + description: | + Provide a detailed description of the issue this hotfix is addressing. + placeholder: "Describe the issue being fixed." + validations: + required: true + + - type: textarea + id: hotfix_solution + attributes: + label: Hotfix Solution + description: | + Explain the solution being implemented in this hotfix. + placeholder: "Describe the solution." + validations: + required: true + + - type: textarea + id: additional_context + attributes: + label: Additional Context + description: | + Add any additional details or context about this hotfix request. + placeholder: "Anything else to note?" diff --git a/setup/ISSUE_TEMPLATE/release.yml b/setup/ISSUE_TEMPLATE/release.yml new file mode 100644 index 00000000..da4884d1 --- /dev/null +++ b/setup/ISSUE_TEMPLATE/release.yml @@ -0,0 +1,51 @@ +name: 🚀 Release Issue +description: Request a new release for copilot (only team members) +title: "" +labels: ["release", "branched", "priority: medium"] +body: + - type: markdown + attributes: + value: | + ### ⚠️ Disclaimer + > **Only members of the copilot team can create release issues.** + > Any release issue created by someone outside the team will be closed automatically. + + --- + + - type: dropdown + id: release_type + attributes: + label: Release Type + description: Indicate the type of release. + options: + - Patch + - Minor + - Major + validations: + required: true + + - type: input + id: version + attributes: + label: Release Version + description: The new version is generated from the release type and the most recent tag version. You can specify a different version number for the release (e.g., 1.2.3). + placeholder: "e.g., 1.2.3" + value: "Automatic" + validations: + required: false + + - type: textarea + id: changelog + attributes: + label: Changelog + description: Provide a summary of the changes to be included in this release. + placeholder: "Add a concise changelog here." + validations: + required: true + + - type: textarea + id: additional_context + attributes: + label: Additional Context + description: Add any additional details or context about this release request. + placeholder: "Anything else to note?" diff --git a/setup/pull_request_template.md b/setup/pull_request_template.md new file mode 100644 index 00000000..633a41b3 --- /dev/null +++ b/setup/pull_request_template.md @@ -0,0 +1,144 @@ + + +# 📌 Summary + + +--- + +## 🎯 Related Issues / Tickets + +- Closes # +- Related to # + +--- + +## 🧩 Scope of Changes + +- Added: +- Updated: +- Removed: +- Refactored: + +--- + +## 🛠️ Technical Details + + +--- + +## 🔍 How to Test + +1. +2. +3. + +--- + +## 🧪 Test Coverage + +- [ ] Unit tests +- [ ] Integration tests +- [ ] End-to-end (E2E) tests +- [ ] Manual testing only (explain why) + +--- + +## 📸 Screenshots / Recordings (UI changes only) + + +--- + +## ⚠️ Breaking Changes + +- None + +--- + +## 🚀 Deployment Notes + +- [ ] Requires database migration +- [ ] Requires environment variable changes +- [ ] Requires feature flag toggle +- [ ] No special deployment steps + +Details: + +--- + +## 🔒 Security Considerations + +- [ ] No security impact +- [ ] Input validation changes +- [ ] Authentication / authorization changes +- [ ] Sensitive data handling changes + +--- + +## 📈 Performance Impact + +- [ ] No performance impact +- [ ] Improves performance +- [ ] Potential performance regression (explain) + +--- + +## 📝 Notes for Reviewers + + +--- + +## ✅ Checklist + +- [ ] I have self-reviewed my code +- [ ] Code follows project standards and conventions +- [ ] Tests have been added or updated +- [ ] Documentation has been updated (if applicable) +- [ ] No new warnings or lint errors +- [ ] Changes are backward compatible or breaking changes are documented + +--- + +## 📚 Additional Context + diff --git a/setup/workflows/copilot_commit.yml b/setup/workflows/copilot_commit.yml new file mode 100644 index 00000000..84ffacff --- /dev/null +++ b/setup/workflows/copilot_commit.yml @@ -0,0 +1,23 @@ +name: Copilot - Commit + +on: + push: + branches: + - '**' + - '!master' + - '!develop' + +jobs: + copilot-commits: + name: Copilot - Commit + runs-on: ubuntu-latest + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + + - uses: vypdev/copilot@v1 + with: + debug: ${{ vars.DEBUG }} + project-ids: ${{ vars.PROJECT_IDS }} + opencode-model: ${{ vars.OPENCODE_MODEL }} + token: ${{ secrets.PAT }} diff --git a/setup/workflows/copilot_issue.yml b/setup/workflows/copilot_issue.yml new file mode 100644 index 00000000..45c84587 --- /dev/null +++ b/setup/workflows/copilot_issue.yml @@ -0,0 +1,21 @@ +name: Copilot - Issue + +on: + issues: + types: [opened, reopened, edited, labeled, unlabeled, assigned, unassigned] + +jobs: + copilot-issues: + name: Copilot - Issue + runs-on: ubuntu-latest + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + + - uses: vypdev/copilot@v1 + with: + ai-ignore-files: build/* + debug: ${{ vars.DEBUG }} + opencode-model: ${{ vars.OPENCODE_MODEL }} + project-ids: ${{ vars.PROJECT_IDS }} + token: ${{ secrets.PAT }} diff --git a/setup/workflows/copilot_issue_comment.yml b/setup/workflows/copilot_issue_comment.yml new file mode 100644 index 00000000..82857d66 --- /dev/null +++ b/setup/workflows/copilot_issue_comment.yml @@ -0,0 +1,21 @@ +name: Copilot - Issue Comment + +on: + issue_comment: + types: [created, edited] + +jobs: + copilot-issues: + name: Copilot - Issue Comment + runs-on: ubuntu-latest + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + + - uses: vypdev/copilot@v1 + with: + ai-ignore-files: build/* + debug: ${{ vars.DEBUG }} + opencode-model: ${{ vars.OPENCODE_MODEL }} + project-ids: ${{ vars.PROJECT_IDS }} + token: ${{ secrets.PAT }} diff --git a/setup/workflows/copilot_pull_request.yml b/setup/workflows/copilot_pull_request.yml new file mode 100644 index 00000000..d63f8616 --- /dev/null +++ b/setup/workflows/copilot_pull_request.yml @@ -0,0 +1,21 @@ +name: Copilot - Pull Request + +on: + pull_request: + types: [opened, reopened, edited, labeled, unlabeled, closed, assigned, unassigned, synchronize] + +jobs: + copilot-pull-requests: + name: Copilot - Pull Request + runs-on: ubuntu-latest + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + + - uses: vypdev/copilot@v1 + with: + ai-ignore-files: build/* + debug: ${{ vars.DEBUG }} + opencode-model: ${{ vars.OPENCODE_MODEL }} + project-ids: ${{ vars.PROJECT_IDS }} + token: ${{ secrets.PAT }} diff --git a/setup/workflows/copilot_pull_request_comment.yml b/setup/workflows/copilot_pull_request_comment.yml new file mode 100644 index 00000000..ea16a0c1 --- /dev/null +++ b/setup/workflows/copilot_pull_request_comment.yml @@ -0,0 +1,22 @@ +name: Copilot - Pull Request Comment + +on: + pull_request_review_comment: + types: [created, edited] + +jobs: + copilot-pull-requests: + name: Copilot - Pull Request Comment + runs-on: ubuntu-latest + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + + - uses: vypdev/copilot@v1 + with: + ai-ignore-files: build/* + debug: ${{ vars.DEBUG }} + opencode-model: ${{ vars.OPENCODE_MODEL }} + project-ids: ${{ vars.PROJECT_IDS }} + token: ${{ secrets.PAT }} + \ No newline at end of file diff --git a/setup/workflows/hotfix_workflow.yml b/setup/workflows/hotfix_workflow.yml new file mode 100644 index 00000000..ac05b335 --- /dev/null +++ b/setup/workflows/hotfix_workflow.yml @@ -0,0 +1,115 @@ +name: Task - Hotfix + +on: + workflow_dispatch: + inputs: + version: + description: 'Hotfix version' + required: true + default: '1.0.0' + title: + description: 'Title' + required: true + default: 'New Version' + changelog: + description: 'Changelog' + required: true + default: '- Several improvements' + issue: + description: 'Launcher issue' + required: true + default: '-1' + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + prepare-version-files: + name: Prepare files for hotfix + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Validate inputs + env: + VERSION: ${{ github.event.inputs.version }} + ISSUE: ${{ github.event.inputs.issue }} + TITLE: ${{ github.event.inputs.title }} + CHANGELOG: ${{ github.event.inputs.changelog }} + run: | + err=0 + if ! [[ "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + echo "::error::Version must be in semver format (e.g. 1.0.0)." + err=1 + fi + if ! [[ "$ISSUE" =~ ^-?[0-9]+$ ]]; then + echo "::error::Issue must be a number (e.g. 123 or -1)." + err=1 + fi + if [[ ${#TITLE} -gt 1000 ]]; then + echo "::error::Title must be at most 1000 characters." + err=1 + fi + if [[ ${#CHANGELOG} -gt 50000 ]]; then + echo "::error::Changelog must be at most 50000 characters." + err=1 + fi + [[ $err -eq 0 ]] || exit 1 + + # Example: generic step to perform the version update or compilation (uncomment and adjust as needed) + # - name: Generic step + # uses: whatever/action@v1 + + - name: Commit updated package.json and dist directory + uses: EndBug/add-and-commit@v9 + with: + add: './build/ ./package.json' + committer_name: GitHub Actions + committer_email: actions@github.com + default_author: user_info + message: 'gh-action: updated compiled files and bumped version to ${{ github.event.inputs.version }} (hotfix)' + + tag: + name: Publish version + runs-on: ubuntu-latest + needs: [ prepare-version-files ] + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + + - name: Copilot - Create Tag + uses: vypdev/copilot@v1 + if: ${{ success() }} + with: + debug: ${{ vars.DEBUG }} + single-action: 'create_tag' + single-action-issue: '${{ github.event.inputs.issue }}' + single-action-version: '${{ github.event.inputs.version }}' + token: ${{ secrets.PAT }} + + - name: Copilot - Create Release + uses: vypdev/copilot@v1 + if: ${{ success() }} + with: + debug: ${{ vars.DEBUG }} + single-action: 'create_release' + single-action-issue: '${{ github.event.inputs.issue }}' + single-action-version: '${{ github.event.inputs.version }}' + single-action-title: '${{ github.event.inputs.title }}' + single-action-changelog: '${{ github.event.inputs.changelog }}' + token: ${{ secrets.PAT }} + + # Example: generic step to perform the deployment (uncomment and adjust as needed) + # - name: Generic step + # uses: whatever/action@v1 + + - name: Copilot - Deploy success notification + uses: vypdev/copilot@v1 + if: ${{ success() }} + with: + debug: ${{ vars.DEBUG }} + single-action: 'deployed_action' + single-action-issue: '${{ github.event.inputs.issue }}' + opencode-model: ${{ vars.OPENCODE_MODEL }} + token: ${{ secrets.PAT }} diff --git a/setup/workflows/release_workflow.yml b/setup/workflows/release_workflow.yml new file mode 100644 index 00000000..b3c2b8c4 --- /dev/null +++ b/setup/workflows/release_workflow.yml @@ -0,0 +1,115 @@ +name: Task - Release + +on: + workflow_dispatch: + inputs: + version: + description: 'Release version' + required: true + default: '1.0.0' + title: + description: 'Title' + required: true + default: 'New Version' + changelog: + description: 'Changelog' + required: true + default: '- Several improvements' + issue: + description: 'Launcher issue' + required: true + default: '-1' + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + prepare-version-files: + name: Prepare files for release + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Validate inputs + env: + VERSION: ${{ github.event.inputs.version }} + ISSUE: ${{ github.event.inputs.issue }} + TITLE: ${{ github.event.inputs.title }} + CHANGELOG: ${{ github.event.inputs.changelog }} + run: | + err=0 + if ! [[ "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + echo "::error::Version must be in semver format (e.g. 1.0.0)." + err=1 + fi + if ! [[ "$ISSUE" =~ ^-?[0-9]+$ ]]; then + echo "::error::Issue must be a number (e.g. 123 or -1)." + err=1 + fi + if [[ ${#TITLE} -gt 1000 ]]; then + echo "::error::Title must be at most 1000 characters." + err=1 + fi + if [[ ${#CHANGELOG} -gt 50000 ]]; then + echo "::error::Changelog must be at most 50000 characters." + err=1 + fi + [[ $err -eq 0 ]] || exit 1 + + # Example: generic step to perform the version update or compilation (uncomment and adjust as needed) + # - name: Generic step + # uses: whatever/action@v1 + + - name: Commit updated package.json and dist directory + uses: EndBug/add-and-commit@v9 + with: + add: './build/ ./package.json' + committer_name: GitHub Actions + committer_email: actions@github.com + default_author: user_info + message: 'gh-action: updated compiled files and bumped version to ${{ github.event.inputs.version }} (release)' + + tag: + name: Publish version + runs-on: ubuntu-latest + needs: [ prepare-version-files ] + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + + - name: Copilot - Create Tag + uses: vypdev/copilot@v1 + if: ${{ success() }} + with: + debug: ${{ vars.DEBUG }} + single-action: 'create_tag' + single-action-issue: '${{ github.event.inputs.issue }}' + single-action-version: '${{ github.event.inputs.version }}' + token: ${{ secrets.PAT }} + + - name: Copilot - Create Release + uses: vypdev/copilot@v1 + if: ${{ success() }} + with: + debug: ${{ vars.DEBUG }} + single-action: 'create_release' + single-action-issue: '${{ github.event.inputs.issue }}' + single-action-version: '${{ github.event.inputs.version }}' + single-action-title: '${{ github.event.inputs.title }}' + single-action-changelog: '${{ github.event.inputs.changelog }}' + token: ${{ secrets.PAT }} + + # Example: generic step to perform the deployment (uncomment and adjust as needed) + # - name: Generic step + # uses: whatever/action@v1 + + - name: Copilot - Deploy success notification + uses: vypdev/copilot@v1 + if: ${{ success() }} + with: + debug: ${{ vars.DEBUG }} + single-action: 'deployed_action' + single-action-issue: '${{ github.event.inputs.issue }}' + opencode-model: ${{ vars.OPENCODE_MODEL }} + token: ${{ secrets.PAT }} diff --git a/src/cli.ts b/src/cli.ts index fc8c25e3..a01205c1 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -6,6 +6,7 @@ import * as dotenv from 'dotenv'; import { runLocalAction } from './actions/local_action'; import { IssueRepository } from './data/repository/issue_repository'; import { ACTIONS, ERRORS, INPUT_KEYS, OPENCODE_DEFAULT_MODEL, TITLE } from './utils/constants'; +import { logError, logInfo } from './utils/logger'; import { Ai } from './data/model/ai'; import { AiRepository, getSessionDiff, OpenCodeFileDiff } from './data/repository/ai_repository'; @@ -59,8 +60,8 @@ program const gitInfo = getGitInfo(); if ('error' in gitInfo) { - console.log(gitInfo.error); - return; + logError(gitInfo.error); + process.exit(1); } // Helper function to clean CLI arguments that may have '=' prefix @@ -137,19 +138,18 @@ program `Question: ${question.substring(0, 100)}${question.length > 100 ? '...' : ''}`, ]; - // logInfo(JSON.stringify(params, null, 2)); runLocalAction(params); }); /** - * Copilot - AI development assistant using OpenCode "build" agent. + * Do - AI development assistant using OpenCode "build" agent. * When the OpenCode server is run locally from your repo (e.g. opencode serve), the build agent * can read and write files; changes are applied in the server workspace. */ program - .command('copilot') + .command('do') .description(`${TITLE} - AI development assistant (OpenCode build agent; can edit files when run locally)`) - .option('-p, --prompt ', 'Prompt or question for the copilot (required)', '') + .option('-p, --prompt ', 'Prompt or question (required)', '') .option('-d, --debug', 'Debug mode', false) .option('--opencode-server-url ', 'OpenCode server URL', process.env.OPENCODE_SERVER_URL || 'http://127.0.0.1:4096') .option('--opencode-model ', 'OpenCode model', process.env.OPENCODE_MODEL) @@ -158,8 +158,8 @@ program const gitInfo = getGitInfo(); if ('error' in gitInfo) { - console.log(gitInfo.error); - return; + logError(gitInfo.error); + process.exit(1); } // Helper function to clean CLI arguments that may have '=' prefix @@ -196,7 +196,7 @@ program const result = await aiRepository.copilotMessage(ai, prompt); if (!result) { - console.error('❌ Copilot request failed (check OpenCode server and model).'); + console.error('❌ Request failed (check OpenCode server and model).'); process.exit(1); } @@ -209,7 +209,7 @@ program } console.log('\n' + '='.repeat(80)); - console.log('🤖 COPILOT RESPONSE (OpenCode build agent)'); + console.log('🤖 RESPONSE (OpenCode build agent)'); console.log('='.repeat(80)); console.log(`\n${text || '(No text response)'}\n`); @@ -226,7 +226,7 @@ program } } catch (error: unknown) { const err = error instanceof Error ? error : new Error(String(error)); - console.error('❌ Error executing copilot:', err.message || error); + console.error('❌ Error executing do:', err.message || error); if (options.debug) { console.error(error); } @@ -250,8 +250,8 @@ program const gitInfo = getGitInfo(); if ('error' in gitInfo) { - console.log(gitInfo.error); - return; + logError(gitInfo.error); + process.exit(1); } // Helper function to clean CLI arguments that may have '=' prefix @@ -333,8 +333,8 @@ program .action(async (options) => { const gitInfo = getGitInfo(); if ('error' in gitInfo) { - console.log(gitInfo.error); - return; + logError(gitInfo.error); + process.exit(1); } const cleanArg = (v: unknown): string => (v != null ? (String(v).startsWith('=') ? String(v).substring(1) : String(v)) : ''); const issueNumber = cleanArg(options.issue); @@ -374,8 +374,8 @@ program .action(async (options) => { const gitInfo = getGitInfo(); if ('error' in gitInfo) { - console.log(gitInfo.error); - return; + logError(gitInfo.error); + process.exit(1); } const cleanArg = (v: unknown): string => (v != null ? (String(v).startsWith('=') ? String(v).substring(1) : String(v)) : ''); const issueNumber = cleanArg(options.issue); @@ -413,6 +413,16 @@ program } }); +/** Returns true if cwd is inside a git repository (work tree). */ +function isInsideGitRepo(cwd: string): boolean { + try { + execSync('git rev-parse --is-inside-work-tree', { cwd, stdio: 'pipe' }); + return true; + } catch { + return false; + } +} + /** * Run the initial setup to configure labels, issue types, and verify access. */ @@ -421,14 +431,26 @@ program .description(`${TITLE} - Initial setup: create labels, issue types, and verify access`) .option('-d, --debug', 'Debug mode', false) .option('-t, --token ', 'Personal access token', process.env.PERSONAL_ACCESS_TOKEN) - .action(async (options) => { + .action(async (options) => { + const cwd = process.cwd(); + + logInfo('🔍 Checking we are inside a git repository...'); + if (!isInsideGitRepo(cwd)) { + logError('❌ Not a git repository. Run "copilot setup" from the root of a git repo.'); + process.exit(1); + } + logInfo('✅ Git repository detected.'); + + logInfo('🔗 Resolving repository (owner/repo)...'); const gitInfo = getGitInfo(); - if ('error' in gitInfo) { - console.log(gitInfo.error); - return; + logError(gitInfo.error); + process.exit(1); } - + logInfo(`📦 Repository: ${gitInfo.owner}/${gitInfo.repo}`); + + logInfo('⚙️ Running initial setup (labels, issue types, access)...'); + const params: any = { // eslint-disable-line @typescript-eslint/no-explicit-any -- CLI options map to action inputs [INPUT_KEYS.DEBUG]: options.debug.toString(), [INPUT_KEYS.SINGLE_ACTION]: ACTIONS.INITIAL_SETUP, diff --git a/src/data/repository/ai_repository.ts b/src/data/repository/ai_repository.ts index 20e8d5a5..e013eca2 100644 --- a/src/data/repository/ai_repository.ts +++ b/src/data/repository/ai_repository.ts @@ -338,7 +338,7 @@ async function opencodeMessageWithAgentRaw( ); const base = ensureNoTrailingSlash(baseUrl); const signal = createTimeoutSignal(OPENCODE_REQUEST_TIMEOUT_MS); - const sessionBody = { title: 'gbf' }; + const sessionBody = { title: 'copilot' }; logDebugInfo(`OpenCode session create body: ${JSON.stringify(sessionBody)}`); const createRes = await fetch(`${base}/session`, { method: 'POST', diff --git a/src/data/repository/branch_repository.ts b/src/data/repository/branch_repository.ts index edc62ebe..1c524338 100644 --- a/src/data/repository/branch_repository.ts +++ b/src/data/repository/branch_repository.ts @@ -525,7 +525,7 @@ This PR merges **${head}** into **${base}**. repo: repository, pull_number: pullRequest.number, body: prBody + '\n' + commitMessages.map(msg => `- ${msg}`).join('\n') + - '\n\nThis PR was automatically created by [`git-board-flow`](https://github.com/landamessenger/git-board-flow).' + '\n\nThis PR was automatically created by [`copilot`](https://github.com/vypdev/copilot).' }); const iteration = 10; diff --git a/src/manager/description/base/content_interface.ts b/src/manager/description/base/content_interface.ts index 37c0783c..f995f6aa 100644 --- a/src/manager/description/base/content_interface.ts +++ b/src/manager/description/base/content_interface.ts @@ -4,7 +4,7 @@ export abstract class ContentInterface { abstract get id(): string private get _id(): string { - return `git-board-flow-${this.id}` + return `copilot-${this.id}` } abstract get visibleContent(): boolean diff --git a/src/usecase/actions/__tests__/create_release_use_case.test.ts b/src/usecase/actions/__tests__/create_release_use_case.test.ts new file mode 100644 index 00000000..99540bfe --- /dev/null +++ b/src/usecase/actions/__tests__/create_release_use_case.test.ts @@ -0,0 +1,100 @@ +import { CreateReleaseUseCase } from '../create_release_use_case'; +import { Result } from '../../../data/model/result'; +import { INPUT_KEYS } from '../../../utils/constants'; +import type { Execution } from '../../../data/model/execution'; + +jest.mock('../../../utils/logger', () => ({ + logInfo: jest.fn(), + logError: jest.fn(), +})); + +jest.mock('../../../utils/task_emoji', () => ({ + getTaskEmoji: jest.fn(() => '🚀'), +})); + +const mockCreateRelease = jest.fn(); +jest.mock('../../../data/repository/project_repository', () => ({ + ProjectRepository: jest.fn().mockImplementation(() => ({ + createRelease: mockCreateRelease, + })), +})); + +function baseParam(overrides: Record = {}): Execution { + return { + owner: 'owner', + repo: 'repo', + tokens: { token: 'token' }, + singleAction: { + version: '1.0.0', + title: 'Release title', + changelog: '- Fix bug', + }, + currentConfiguration: {}, + ...overrides, + } as unknown as Execution; +} + +describe('CreateReleaseUseCase', () => { + let useCase: CreateReleaseUseCase; + + beforeEach(() => { + useCase = new CreateReleaseUseCase(); + mockCreateRelease.mockReset(); + }); + + it('returns failure when version is empty', async () => { + const param = baseParam({ singleAction: { version: '', title: 't', changelog: 'c' } }); + const results = await useCase.invoke(param); + expect(results).toHaveLength(1); + expect(results[0].success).toBe(false); + expect(results[0].errors?.some((e) => String(e).includes(INPUT_KEYS.SINGLE_ACTION_VERSION))).toBe(true); + }); + + it('returns failure when title is empty', async () => { + const param = baseParam({ singleAction: { version: '1.0.0', title: '', changelog: 'c' } }); + const results = await useCase.invoke(param); + expect(results.length).toBeGreaterThanOrEqual(1); + expect(results.some((r) => r.errors?.some((e) => String(e).includes(`${INPUT_KEYS.SINGLE_ACTION_TITLE} is not set.`)))).toBe(true); + }); + + it('returns failure when changelog is empty', async () => { + const param = baseParam({ singleAction: { version: '1.0.0', title: 't', changelog: '' } }); + const results = await useCase.invoke(param); + expect(results.length).toBeGreaterThanOrEqual(1); + expect(results.some((r) => r.errors?.some((e) => String(e).includes(`${INPUT_KEYS.SINGLE_ACTION_CHANGELOG} is not set.`)))).toBe(true); + }); + + it('returns success with release URL when createRelease succeeds', async () => { + mockCreateRelease.mockResolvedValue('https://github.com/owner/repo/releases/tag/v1.0.0'); + const param = baseParam(); + const results = await useCase.invoke(param); + expect(results).toHaveLength(1); + expect(results[0]).toBeInstanceOf(Result); + expect(results[0].success).toBe(true); + expect(results[0].steps?.some((s) => s.includes('Created release'))).toBe(true); + expect(mockCreateRelease).toHaveBeenCalledWith( + 'owner', + 'repo', + '1.0.0', + 'Release title', + '- Fix bug', + 'token' + ); + }); + + it('returns failure when createRelease returns null', async () => { + mockCreateRelease.mockResolvedValue(null); + const param = baseParam(); + const results = await useCase.invoke(param); + expect(results[0].success).toBe(false); + expect(results[0].errors).toContain('Failed to create release.'); + }); + + it('returns failure and catches error when createRelease throws', async () => { + mockCreateRelease.mockRejectedValue(new Error('API error')); + const param = baseParam(); + const results = await useCase.invoke(param); + expect(results[0].success).toBe(false); + expect(results[0].errors?.length).toBeGreaterThan(0); + }); +}); diff --git a/src/usecase/actions/__tests__/create_tag_use_case.test.ts b/src/usecase/actions/__tests__/create_tag_use_case.test.ts new file mode 100644 index 00000000..d82c0e80 --- /dev/null +++ b/src/usecase/actions/__tests__/create_tag_use_case.test.ts @@ -0,0 +1,88 @@ +import { CreateTagUseCase } from '../create_tag_use_case'; +import { Result } from '../../../data/model/result'; +import { INPUT_KEYS } from '../../../utils/constants'; +import type { Execution } from '../../../data/model/execution'; + +jest.mock('../../../utils/logger', () => ({ + logInfo: jest.fn(), + logError: jest.fn(), +})); + +jest.mock('../../../utils/task_emoji', () => ({ + getTaskEmoji: jest.fn(() => '🏷️'), +})); + +const mockCreateTag = jest.fn(); +jest.mock('../../../data/repository/project_repository', () => ({ + ProjectRepository: jest.fn().mockImplementation(() => ({ + createTag: mockCreateTag, + })), +})); + +function baseParam(overrides: Record = {}): Execution { + return { + owner: 'owner', + repo: 'repo', + tokens: { token: 'token' }, + singleAction: { version: '1.0.0' }, + currentConfiguration: { releaseBranch: 'release/1.0.0' }, + ...overrides, + } as unknown as Execution; +} + +describe('CreateTagUseCase', () => { + let useCase: CreateTagUseCase; + + beforeEach(() => { + useCase = new CreateTagUseCase(); + mockCreateTag.mockReset(); + }); + + it('returns failure when version is empty', async () => { + const param = baseParam({ singleAction: { version: '' } }); + const results = await useCase.invoke(param); + expect(results).toHaveLength(1); + expect(results[0].success).toBe(false); + expect(results[0].errors).toContain(`${INPUT_KEYS.SINGLE_ACTION_VERSION} is not set.`); + }); + + it('returns failure when releaseBranch is undefined', async () => { + const param = baseParam({ currentConfiguration: { releaseBranch: undefined } }); + const results = await useCase.invoke(param); + expect(results).toHaveLength(1); + expect(results[0].success).toBe(false); + expect(results[0].errors).toContain('Release branch not found in issue configuration.'); + }); + + it('returns success with step when createTag succeeds', async () => { + mockCreateTag.mockResolvedValue('abc123'); + const param = baseParam(); + const results = await useCase.invoke(param); + expect(results).toHaveLength(1); + expect(results[0]).toBeInstanceOf(Result); + expect(results[0].success).toBe(true); + expect(results[0].steps?.some((s) => s.includes('1.0.0') && s.includes('abc123'))).toBe(true); + expect(mockCreateTag).toHaveBeenCalledWith( + 'owner', + 'repo', + 'release/1.0.0', + '1.0.0', + 'token' + ); + }); + + it('returns failure when createTag returns null', async () => { + mockCreateTag.mockResolvedValue(null); + const param = baseParam(); + const results = await useCase.invoke(param); + expect(results[0].success).toBe(false); + expect(results[0].errors?.some((e) => String(e).includes('Failed to create tag'))).toBe(true); + }); + + it('returns failure when createTag throws', async () => { + mockCreateTag.mockRejectedValue(new Error('API error')); + const param = baseParam(); + const results = await useCase.invoke(param); + expect(results[0].success).toBe(false); + }); +}); diff --git a/src/usecase/actions/__tests__/initial_setup_use_case.test.ts b/src/usecase/actions/__tests__/initial_setup_use_case.test.ts new file mode 100644 index 00000000..d68c71f9 --- /dev/null +++ b/src/usecase/actions/__tests__/initial_setup_use_case.test.ts @@ -0,0 +1,125 @@ +import { InitialSetupUseCase } from '../initial_setup_use_case'; +import { Result } from '../../../data/model/result'; +import type { Execution } from '../../../data/model/execution'; + +jest.mock('../../../utils/logger', () => ({ + logInfo: jest.fn(), + logError: jest.fn(), +})); + +jest.mock('../../../utils/task_emoji', () => ({ + getTaskEmoji: jest.fn(() => '📋'), +})); + +const mockEnsureGitHubDirs = jest.fn(); +const mockCopySetupFiles = jest.fn(); +jest.mock('../../../utils/setup_files', () => ({ + ensureGitHubDirs: (...args: unknown[]) => mockEnsureGitHubDirs(...args), + copySetupFiles: (...args: unknown[]) => mockCopySetupFiles(...args), +})); + +const mockGetUserFromToken = jest.fn(); +jest.mock('../../../data/repository/project_repository', () => ({ + ProjectRepository: jest.fn().mockImplementation(() => ({ + getUserFromToken: mockGetUserFromToken, + })), +})); + +const mockEnsureLabels = jest.fn(); +const mockEnsureProgressLabels = jest.fn(); +const mockEnsureIssueTypes = jest.fn(); +jest.mock('../../../data/repository/issue_repository', () => ({ + IssueRepository: jest.fn().mockImplementation(() => ({ + ensureLabels: mockEnsureLabels, + ensureProgressLabels: mockEnsureProgressLabels, + ensureIssueTypes: mockEnsureIssueTypes, + })), +})); + +function baseParam(overrides: Record = {}): Execution { + return { + owner: 'owner', + repo: 'repo', + tokens: { token: 'token' }, + labels: {}, + issueTypes: {}, + singleAction: {}, + currentConfiguration: {}, + branches: {}, + release: {}, + hotfix: {}, + issue: {}, + pullRequest: {}, + workflows: {}, + project: { getProjects: () => [], getProjectColumnIssueCreated: () => '', getProjectColumnIssueInProgress: () => '' }, + commit: {}, + commitPrefixBuilder: '', + emoji: {}, + images: {}, + ai: {}, + locale: {}, + sizeThresholds: {}, + ...overrides, + } as unknown as Execution; +} + +describe('InitialSetupUseCase', () => { + let useCase: InitialSetupUseCase; + + beforeEach(() => { + useCase = new InitialSetupUseCase(); + mockEnsureGitHubDirs.mockClear(); + mockCopySetupFiles.mockReturnValue({ copied: 2, skipped: 0 }); + mockGetUserFromToken.mockResolvedValue('test-user'); + mockEnsureLabels.mockResolvedValue({ success: true, created: 0, existing: 5, errors: [] }); + mockEnsureProgressLabels.mockResolvedValue({ created: 0, existing: 21, errors: [] }); + mockEnsureIssueTypes.mockResolvedValue({ success: true, created: 0, existing: 3, errors: [] }); + }); + + it('calls ensureGitHubDirs and copySetupFiles with process.cwd()', async () => { + const param = baseParam(); + await useCase.invoke(param); + expect(mockEnsureGitHubDirs).toHaveBeenCalledWith(process.cwd()); + expect(mockCopySetupFiles).toHaveBeenCalledWith(process.cwd()); + }); + + it('returns success and steps including setup files when all steps succeed', async () => { + const param = baseParam(); + const results = await useCase.invoke(param); + expect(results).toHaveLength(1); + expect(results[0]).toBeInstanceOf(Result); + expect(results[0].success).toBe(true); + expect(results[0].steps?.some((s) => s.includes('Setup files'))).toBe(true); + expect(results[0].steps?.some((s) => s.includes('GitHub access verified'))).toBe(true); + expect(results[0].steps?.some((s) => s.includes('Labels checked'))).toBe(true); + expect(results[0].steps?.some((s) => s.includes('Progress labels'))).toBe(true); + expect(results[0].steps?.some((s) => s.includes('Issue types'))).toBe(true); + }); + + it('returns failure when verifyGitHubAccess fails', async () => { + mockGetUserFromToken.mockRejectedValue(new Error('Invalid token')); + const param = baseParam(); + const results = await useCase.invoke(param); + expect(results).toHaveLength(1); + expect(results[0].success).toBe(false); + expect(results[0].errors?.length).toBeGreaterThan(0); + }); + + it('continues and reports errors when ensureLabels fails', async () => { + mockEnsureLabels.mockResolvedValue({ success: false, created: 0, existing: 0, errors: ['Label error'] }); + const param = baseParam(); + const results = await useCase.invoke(param); + expect(results).toHaveLength(1); + expect(results[0].success).toBe(false); + expect(results[0].errors).toContain('Label error'); + }); + + it('continues and reports errors when ensureProgressLabels has errors', async () => { + mockEnsureProgressLabels.mockResolvedValue({ created: 0, existing: 0, errors: ['Progress error'] }); + const param = baseParam(); + const results = await useCase.invoke(param); + expect(results).toHaveLength(1); + expect(results[0].success).toBe(false); + expect(results[0].errors).toContain('Progress error'); + }); +}); diff --git a/src/usecase/actions/__tests__/publish_github_action_use_case.test.ts b/src/usecase/actions/__tests__/publish_github_action_use_case.test.ts new file mode 100644 index 00000000..63645865 --- /dev/null +++ b/src/usecase/actions/__tests__/publish_github_action_use_case.test.ts @@ -0,0 +1,83 @@ +import { PublishGithubActionUseCase } from '../publish_github_action_use_case'; +import { Result } from '../../../data/model/result'; +import { INPUT_KEYS } from '../../../utils/constants'; +import type { Execution } from '../../../data/model/execution'; + +jest.mock('../../../utils/logger', () => ({ + logInfo: jest.fn(), + logError: jest.fn(), +})); + +jest.mock('../../../utils/task_emoji', () => ({ + getTaskEmoji: jest.fn(() => '📦'), +})); + +const mockUpdateTag = jest.fn(); +const mockUpdateRelease = jest.fn(); +jest.mock('../../../data/repository/project_repository', () => ({ + ProjectRepository: jest.fn().mockImplementation(() => ({ + updateTag: mockUpdateTag, + updateRelease: mockUpdateRelease, + })), +})); + +function baseParam(overrides: Record = {}): Execution { + return { + owner: 'owner', + repo: 'repo', + tokens: { token: 'token' }, + singleAction: { version: '1.2.3' }, + ...overrides, + } as unknown as Execution; +} + +describe('PublishGithubActionUseCase', () => { + let useCase: PublishGithubActionUseCase; + + beforeEach(() => { + useCase = new PublishGithubActionUseCase(); + mockUpdateTag.mockResolvedValue(undefined); + mockUpdateRelease.mockReset(); + }); + + it('returns failure when version is empty', async () => { + const param = baseParam({ singleAction: { version: '' } }); + const results = await useCase.invoke(param); + expect(results).toHaveLength(1); + expect(results[0].success).toBe(false); + expect(results[0].errors).toContain(`${INPUT_KEYS.SINGLE_ACTION_VERSION} is not set.`); + }); + + it('calls updateTag with v{version} and major segment, then updateRelease', async () => { + mockUpdateRelease.mockResolvedValue(12345); + const param = baseParam({ singleAction: { version: '1.2.3' } }); + await useCase.invoke(param); + expect(mockUpdateTag).toHaveBeenCalledWith('owner', 'repo', 'v1.2.3', 'v1', 'token'); + expect(mockUpdateRelease).toHaveBeenCalledWith('owner', 'repo', 'v1.2.3', 'v1', 'token'); + }); + + it('returns success when updateRelease returns truthy', async () => { + mockUpdateRelease.mockResolvedValue(999); + const param = baseParam(); + const results = await useCase.invoke(param); + expect(results).toHaveLength(1); + expect(results[0]).toBeInstanceOf(Result); + expect(results[0].success).toBe(true); + expect(results[0].steps?.some((s) => s.includes('v1.2.3') && s.includes('v1'))).toBe(true); + }); + + it('returns failure when updateRelease returns falsy', async () => { + mockUpdateRelease.mockResolvedValue(null); + const param = baseParam(); + const results = await useCase.invoke(param); + expect(results[0].success).toBe(false); + expect(results[0].errors?.some((e) => String(e).includes('Failed to update release'))).toBe(true); + }); + + it('returns failure when updateTag or updateRelease throws', async () => { + mockUpdateTag.mockRejectedValue(new Error('Tag error')); + const param = baseParam(); + const results = await useCase.invoke(param); + expect(results[0].success).toBe(false); + }); +}); diff --git a/src/usecase/actions/__tests__/recommend_steps_use_case.test.ts b/src/usecase/actions/__tests__/recommend_steps_use_case.test.ts new file mode 100644 index 00000000..34044a55 --- /dev/null +++ b/src/usecase/actions/__tests__/recommend_steps_use_case.test.ts @@ -0,0 +1,102 @@ +import { RecommendStepsUseCase } from '../recommend_steps_use_case'; +import { Ai } from '../../../data/model/ai'; +import type { Execution } from '../../../data/model/execution'; + +jest.mock('../../../utils/logger', () => ({ + logInfo: jest.fn(), + logError: jest.fn(), +})); + +jest.mock('../../../utils/task_emoji', () => ({ + getTaskEmoji: jest.fn(() => '💡'), +})); + +const mockGetDescription = jest.fn(); +jest.mock('../../../data/repository/issue_repository', () => ({ + IssueRepository: jest.fn().mockImplementation(() => ({ + getDescription: mockGetDescription, + })), +})); + +const mockAskAgent = jest.fn(); +jest.mock('../../../data/repository/ai_repository', () => ({ + AiRepository: jest.fn().mockImplementation(() => ({ + askAgent: mockAskAgent, + })), + OPENCODE_AGENT_PLAN: 'plan', +})); + +function baseParam(overrides: Record = {}): Execution { + return { + owner: 'owner', + repo: 'repo', + issueNumber: 42, + tokens: { token: 'token' }, + ai: new Ai('http://localhost:4096', 'opencode/model', false, false, [], false, 'low', 20), + ...overrides, + } as unknown as Execution; +} + +describe('RecommendStepsUseCase', () => { + let useCase: RecommendStepsUseCase; + + beforeEach(() => { + useCase = new RecommendStepsUseCase(); + mockGetDescription.mockReset(); + mockAskAgent.mockReset(); + }); + + it('returns failure when ai has no opencode model or server URL', async () => { + const param = baseParam({ ai: new Ai('', '', false, false, [], false, 'low', 20) }); + const results = await useCase.invoke(param); + expect(results).toHaveLength(1); + expect(results[0].success).toBe(false); + expect(results[0].errors).toContain('Missing OPENCODE_SERVER_URL and OPENCODE_MODEL.'); + }); + + it('returns failure when issueNumber is -1', async () => { + const param = baseParam({ issueNumber: -1 }); + const results = await useCase.invoke(param); + expect(results).toHaveLength(1); + expect(results[0].success).toBe(false); + expect(results[0].errors).toContain('Issue number not found.'); + }); + + it('returns failure when issue description is empty or missing', async () => { + mockGetDescription.mockResolvedValue(''); + const param = baseParam(); + const results = await useCase.invoke(param); + expect(results).toHaveLength(1); + expect(results[0].success).toBe(false); + expect(results[0].errors?.some((e) => String(e).includes('No description found'))).toBe(true); + }); + + it('returns success with recommended steps when AI returns string', async () => { + mockGetDescription.mockResolvedValue('Implement login feature.'); + mockAskAgent.mockResolvedValue('1. Add auth module\n2. Add tests'); + const param = baseParam(); + const results = await useCase.invoke(param); + expect(results).toHaveLength(1); + expect(results[0].success).toBe(true); + expect(results[0].steps).toBeDefined(); + expect(results[0].payload?.recommendedSteps).toContain('1. Add auth module'); + }); + + it('returns success when AI returns object with steps', async () => { + mockGetDescription.mockResolvedValue('Fix bug.'); + mockAskAgent.mockResolvedValue({ steps: '1. Reproduce\n2. Fix' }); + const param = baseParam(); + const results = await useCase.invoke(param); + expect(results[0].success).toBe(true); + expect(results[0].payload?.recommendedSteps).toContain('1. Reproduce'); + }); + + it('returns failure when askAgent throws', async () => { + mockGetDescription.mockResolvedValue('Do something'); + mockAskAgent.mockRejectedValue(new Error('AI error')); + const param = baseParam(); + const results = await useCase.invoke(param); + expect(results[0].success).toBe(false); + expect(results[0].errors?.length).toBeGreaterThan(0); + }); +}); diff --git a/src/usecase/actions/check_progress_use_case.ts b/src/usecase/actions/check_progress_use_case.ts index 12b8c4c9..b6667d00 100644 --- a/src/usecase/actions/check_progress_use_case.ts +++ b/src/usecase/actions/check_progress_use_case.ts @@ -2,6 +2,7 @@ import { Ai } from '../../data/model/ai'; import { Execution } from '../../data/model/execution'; import { Result } from '../../data/model/result'; import { logError, logInfo } from '../../utils/logger'; +import { getTaskEmoji } from '../../utils/task_emoji'; import { ParamUseCase } from '../base/param_usecase'; import { IssueRepository, PROGRESS_LABEL_PATTERN } from '../../data/repository/issue_repository'; import { BranchRepository } from '../../data/repository/branch_repository'; @@ -34,7 +35,7 @@ export class CheckProgressUseCase implements ParamUseCase { private aiRepository: AiRepository = new AiRepository(); async invoke(param: Execution): Promise { - logInfo(`Executing ${this.taskId}.`); + logInfo(`${getTaskEmoji(this.taskId)} Executing ${this.taskId}.`); const results: Result[] = []; diff --git a/src/usecase/actions/create_release_use_case.ts b/src/usecase/actions/create_release_use_case.ts index 623d0a99..f91fc34e 100644 --- a/src/usecase/actions/create_release_use_case.ts +++ b/src/usecase/actions/create_release_use_case.ts @@ -3,6 +3,7 @@ import { Result } from "../../data/model/result"; import { ProjectRepository } from "../../data/repository/project_repository"; import { INPUT_KEYS } from "../../utils/constants"; import { logError, logInfo } from "../../utils/logger"; +import { getTaskEmoji } from "../../utils/task_emoji"; import { ParamUseCase } from "../base/param_usecase"; @@ -12,7 +13,7 @@ export class CreateReleaseUseCase implements ParamUseCase private projectRepository = new ProjectRepository(); async invoke(param: Execution): Promise { - logInfo(`Executing ${this.taskId}.`); + logInfo(`${getTaskEmoji(this.taskId)} Executing ${this.taskId}.`); const result: Result[] = []; diff --git a/src/usecase/actions/create_tag_use_case.ts b/src/usecase/actions/create_tag_use_case.ts index d53b10e8..2fb17a29 100644 --- a/src/usecase/actions/create_tag_use_case.ts +++ b/src/usecase/actions/create_tag_use_case.ts @@ -3,6 +3,7 @@ import { Result } from "../../data/model/result"; import { ProjectRepository } from "../../data/repository/project_repository"; import { INPUT_KEYS } from "../../utils/constants"; import { logError, logInfo } from "../../utils/logger"; +import { getTaskEmoji } from "../../utils/task_emoji"; import { ParamUseCase } from "../base/param_usecase"; @@ -12,7 +13,7 @@ export class CreateTagUseCase implements ParamUseCase { private projectRepository = new ProjectRepository(); async invoke(param: Execution): Promise { - logInfo(`Executing ${this.taskId}.`); + logInfo(`${getTaskEmoji(this.taskId)} Executing ${this.taskId}.`); const result: Result[] = []; diff --git a/src/usecase/actions/deployed_action_use_case.ts b/src/usecase/actions/deployed_action_use_case.ts index 917bab84..6dfd2113 100644 --- a/src/usecase/actions/deployed_action_use_case.ts +++ b/src/usecase/actions/deployed_action_use_case.ts @@ -3,6 +3,7 @@ import { Result } from "../../data/model/result"; import { BranchRepository } from "../../data/repository/branch_repository"; import { IssueRepository } from "../../data/repository/issue_repository"; import { logDebugInfo, logError, logInfo } from "../../utils/logger"; +import { getTaskEmoji } from "../../utils/task_emoji"; import { ParamUseCase } from "../base/param_usecase"; export class DeployedActionUseCase implements ParamUseCase { @@ -11,7 +12,7 @@ export class DeployedActionUseCase implements ParamUseCase private branchRepository = new BranchRepository(); async invoke(param: Execution): Promise { - logInfo(`Executing ${this.taskId}.`); + logInfo(`${getTaskEmoji(this.taskId)} Executing ${this.taskId}.`); const result: Result[] = []; diff --git a/src/usecase/actions/initial_setup_use_case.ts b/src/usecase/actions/initial_setup_use_case.ts index a904b19d..6689df5a 100644 --- a/src/usecase/actions/initial_setup_use_case.ts +++ b/src/usecase/actions/initial_setup_use_case.ts @@ -4,18 +4,26 @@ import { ProjectRepository } from "../../data/repository/project_repository"; import { Result } from "../../data/model/result"; import { ParamUseCase } from "../base/param_usecase"; import { logError, logInfo } from "../../utils/logger"; +import { getTaskEmoji } from "../../utils/task_emoji"; +import { copySetupFiles, ensureGitHubDirs } from "../../utils/setup_files"; export class InitialSetupUseCase implements ParamUseCase { taskId: string = 'InitialSetupUseCase'; async invoke(param: Execution): Promise { - logInfo(`Executing ${this.taskId}.`); + logInfo(`${getTaskEmoji(this.taskId)} Executing ${this.taskId}.`); const results: Result[] = []; const steps: string[] = []; const errors: string[] = []; try { + // 0. Setup files (.github/workflows, .github/ISSUE_TEMPLATE, pull_request_template.md, .env) + logInfo('📋 Ensuring .github and copying setup files...'); + ensureGitHubDirs(process.cwd()); + const filesResult = copySetupFiles(process.cwd()); + steps.push(`✅ Setup files: ${filesResult.copied} copied, ${filesResult.skipped} already existed`); + // 1. Verificar acceso a GitHub con Personal Access Token logInfo('🔐 Checking GitHub access...'); const githubAccessResult = await this.verifyGitHubAccess(param); diff --git a/src/usecase/actions/publish_github_action_use_case.ts b/src/usecase/actions/publish_github_action_use_case.ts index 918c254f..4e2916ea 100644 --- a/src/usecase/actions/publish_github_action_use_case.ts +++ b/src/usecase/actions/publish_github_action_use_case.ts @@ -3,6 +3,7 @@ import { Result } from "../../data/model/result"; import { ProjectRepository } from "../../data/repository/project_repository"; import { INPUT_KEYS } from "../../utils/constants"; import { logError, logInfo } from "../../utils/logger"; +import { getTaskEmoji } from "../../utils/task_emoji"; import { ParamUseCase } from "../base/param_usecase"; @@ -12,7 +13,7 @@ export class PublishGithubActionUseCase implements ParamUseCase { - logInfo(`Executing ${this.taskId}.`); + logInfo(`${getTaskEmoji(this.taskId)} Executing ${this.taskId}.`); const result: Result[] = []; diff --git a/src/usecase/actions/recommend_steps_use_case.ts b/src/usecase/actions/recommend_steps_use_case.ts index 2c7911f7..4412e743 100644 --- a/src/usecase/actions/recommend_steps_use_case.ts +++ b/src/usecase/actions/recommend_steps_use_case.ts @@ -1,6 +1,7 @@ import { Execution } from '../../data/model/execution'; import { Result } from '../../data/model/result'; import { logError, logInfo } from '../../utils/logger'; +import { getTaskEmoji } from '../../utils/task_emoji'; import { ParamUseCase } from '../base/param_usecase'; import { IssueRepository } from '../../data/repository/issue_repository'; import { AiRepository, OPENCODE_AGENT_PLAN } from '../../data/repository/ai_repository'; @@ -11,7 +12,7 @@ export class RecommendStepsUseCase implements ParamUseCase private aiRepository: AiRepository = new AiRepository(); async invoke(param: Execution): Promise { - logInfo(`Executing ${this.taskId}.`); + logInfo(`${getTaskEmoji(this.taskId)} Executing ${this.taskId}.`); const results: Result[] = []; diff --git a/src/usecase/commit_use_case.ts b/src/usecase/commit_use_case.ts index 807cef75..2824a19d 100644 --- a/src/usecase/commit_use_case.ts +++ b/src/usecase/commit_use_case.ts @@ -1,6 +1,7 @@ import { Execution } from "../data/model/execution"; import { Result } from "../data/model/result"; import { logDebugInfo, logError, logInfo } from "../utils/logger"; +import { getTaskEmoji } from "../utils/task_emoji"; import { ParamUseCase } from "./base/param_usecase"; import { CheckProgressUseCase } from "./actions/check_progress_use_case"; import { NotifyNewCommitOnIssueUseCase } from "./steps/commit/notify_new_commit_on_issue_use_case"; @@ -11,7 +12,7 @@ export class CommitUseCase implements ParamUseCase { taskId: string = 'CommitUseCase'; async invoke(param: Execution): Promise { - logInfo(`Executing ${this.taskId}.`); + logInfo(`${getTaskEmoji(this.taskId)} Executing ${this.taskId}.`); const results: Result[] = []; try { diff --git a/src/usecase/issue_comment_use_case.ts b/src/usecase/issue_comment_use_case.ts index 5485def8..103a8788 100644 --- a/src/usecase/issue_comment_use_case.ts +++ b/src/usecase/issue_comment_use_case.ts @@ -1,6 +1,7 @@ import { Execution } from "../data/model/execution"; import { Result } from "../data/model/result"; import { logInfo } from "../utils/logger"; +import { getTaskEmoji } from "../utils/task_emoji"; import { ThinkUseCase } from "./steps/common/think_use_case"; import { ParamUseCase } from "./base/param_usecase"; import { CheckIssueCommentLanguageUseCase } from "./steps/issue_comment/check_issue_comment_language_use_case"; @@ -9,7 +10,7 @@ export class IssueCommentUseCase implements ParamUseCase { taskId: string = 'IssueCommentUseCase'; async invoke(param: Execution): Promise { - logInfo(`Executing ${this.taskId}.`) + logInfo(`${getTaskEmoji(this.taskId)} Executing ${this.taskId}.`) const results: Result[] = [] diff --git a/src/usecase/issue_use_case.ts b/src/usecase/issue_use_case.ts index ae86ba91..f5fd7005 100644 --- a/src/usecase/issue_use_case.ts +++ b/src/usecase/issue_use_case.ts @@ -1,6 +1,7 @@ import { Execution } from "../data/model/execution"; import { Result } from "../data/model/result"; import { logInfo } from "../utils/logger"; +import { getTaskEmoji } from "../utils/task_emoji"; import { ParamUseCase } from "./base/param_usecase"; import { CheckPermissionsUseCase } from "./steps/common/check_permissions_use_case"; import { UpdateTitleUseCase } from "./steps/common/update_title_use_case"; @@ -19,7 +20,7 @@ export class IssueUseCase implements ParamUseCase { taskId: string = 'IssueUseCase'; async invoke(param: Execution): Promise { - logInfo(`Executing ${this.taskId}.`) + logInfo(`${getTaskEmoji(this.taskId)} Executing ${this.taskId}.`) const results: Result[] = [] diff --git a/src/usecase/pull_request_review_comment_use_case.ts b/src/usecase/pull_request_review_comment_use_case.ts index abef0538..bf8f780a 100644 --- a/src/usecase/pull_request_review_comment_use_case.ts +++ b/src/usecase/pull_request_review_comment_use_case.ts @@ -1,6 +1,7 @@ import { Execution } from "../data/model/execution"; import { Result } from "../data/model/result"; import { logInfo } from "../utils/logger"; +import { getTaskEmoji } from "../utils/task_emoji"; import { ParamUseCase } from "./base/param_usecase"; import { CheckPullRequestCommentLanguageUseCase } from "./steps/pull_request_review_comment/check_pull_request_comment_language_use_case"; @@ -8,7 +9,7 @@ export class PullRequestReviewCommentUseCase implements ParamUseCase { - logInfo(`Executing ${this.taskId}.`) + logInfo(`${getTaskEmoji(this.taskId)} Executing ${this.taskId}.`) const results: Result[] = [] diff --git a/src/usecase/pull_request_use_case.ts b/src/usecase/pull_request_use_case.ts index 39cf8bb5..7791bc4a 100644 --- a/src/usecase/pull_request_use_case.ts +++ b/src/usecase/pull_request_use_case.ts @@ -1,6 +1,7 @@ import { Execution } from "../data/model/execution"; import { Result } from "../data/model/result"; import { logDebugInfo, logError, logInfo } from "../utils/logger"; +import { getTaskEmoji } from "../utils/task_emoji"; import { ParamUseCase } from "./base/param_usecase"; import { UpdateTitleUseCase } from "./steps/common/update_title_use_case"; import { AssignMemberToIssueUseCase } from "./steps/issue/assign_members_to_issue_use_case"; @@ -16,7 +17,7 @@ export class PullRequestUseCase implements ParamUseCase { taskId: string = 'PullRequestUseCase'; async invoke(param: Execution): Promise { - logInfo(`Executing ${this.taskId}.`) + logInfo(`${getTaskEmoji(this.taskId)} Executing ${this.taskId}.`) const results: Result[] = [] try { diff --git a/src/usecase/single_action_use_case.ts b/src/usecase/single_action_use_case.ts index b4079a14..02db1274 100644 --- a/src/usecase/single_action_use_case.ts +++ b/src/usecase/single_action_use_case.ts @@ -1,6 +1,7 @@ import { Execution } from "../data/model/execution"; import { Result } from "../data/model/result"; import { logDebugInfo, logError, logInfo } from "../utils/logger"; +import { getTaskEmoji } from "../utils/task_emoji"; import { DeployedActionUseCase } from "./actions/deployed_action_use_case"; import { ParamUseCase } from "./base/param_usecase"; import { PublishGithubActionUseCase } from "./actions/publish_github_action_use_case"; @@ -16,7 +17,7 @@ export class SingleActionUseCase implements ParamUseCase { taskId: string = 'SingleActionUseCase'; async invoke(param: Execution): Promise { - logInfo(`Executing ${this.taskId}.`) + logInfo(`${getTaskEmoji(this.taskId)} Executing ${this.taskId}.`) const results: Result[] = [] try { diff --git a/src/usecase/steps/commit/__tests__/detect_potential_problems_use_case.test.ts b/src/usecase/steps/commit/__tests__/detect_potential_problems_use_case.test.ts index 37194755..4e91f5a4 100644 --- a/src/usecase/steps/commit/__tests__/detect_potential_problems_use_case.test.ts +++ b/src/usecase/steps/commit/__tests__/detect_potential_problems_use_case.test.ts @@ -207,7 +207,7 @@ describe('DetectPotentialProblemsUseCase', () => { expect(mockAddComment).toHaveBeenCalledTimes(1); expect(mockAddComment).toHaveBeenCalledWith('owner', 'repo', 42, expect.any(String), 'token'); expect(mockAddComment.mock.calls[0][3]).toContain('Possible null dereference'); - expect(mockAddComment.mock.calls[0][3]).toContain('gbf-bugbot'); + expect(mockAddComment.mock.calls[0][3]).toContain('copilot-bugbot'); expect(mockAddComment.mock.calls[0][3]).toContain('finding_id:"src/foo.ts:10:possible-null"'); expect(mockUpdateComment).not.toHaveBeenCalled(); }); @@ -254,7 +254,7 @@ describe('DetectPotentialProblemsUseCase', () => { mockListIssueComments.mockResolvedValue([ { id: 999, - body: `## Existing problem\n\nDetails.\n\n`, + body: `## Existing problem\n\nDetails.\n\n`, user: { login: 'bot' }, }, ]); @@ -270,7 +270,7 @@ describe('DetectPotentialProblemsUseCase', () => { mockListIssueComments.mockResolvedValue([ { id: 888, - body: `## Old bug\n\nDescription.\n\n`, + body: `## Old bug\n\nDescription.\n\n`, user: { login: 'bot' }, }, ]); @@ -303,7 +303,7 @@ describe('DetectPotentialProblemsUseCase', () => { mockListPullRequestReviewComments.mockResolvedValue([ { id: 777, - body: `## PR finding\n\n`, + body: `## PR finding\n\n`, path: 'src/a.ts', line: 1, node_id: 'PRRC_node_777', @@ -336,7 +336,7 @@ describe('DetectPotentialProblemsUseCase', () => { mockListIssueComments.mockResolvedValue([ { id: 666, - body: `## Unfixed\n\n`, + body: `## Unfixed\n\n`, user: {}, }, ]); @@ -370,7 +370,7 @@ describe('DetectPotentialProblemsUseCase', () => { resolved_finding_ids: ['old-1'], }); mockListIssueComments.mockResolvedValue([ - { id: 1, body: '', user: {} }, + { id: 1, body: '', user: {} }, ]); const results = await useCase.invoke(baseParam()); @@ -420,7 +420,7 @@ describe('DetectPotentialProblemsUseCase', () => { mockListPullRequestReviewComments.mockResolvedValue([ { id: 555, - body: `## Same\n\n`, + body: `## Same\n\n`, path: 'x.ts', line: 1, }, @@ -458,7 +458,7 @@ describe('DetectPotentialProblemsUseCase', () => { mockListIssueComments.mockResolvedValue([ { id: 111, - body: `## Extracted Title Here\n\nSome body.\n\n`, + body: `## Extracted Title Here\n\nSome body.\n\n`, user: {}, }, ]); @@ -486,7 +486,7 @@ describe('DetectPotentialProblemsUseCase', () => { mockListIssueComments.mockResolvedValue([ { id: 222, - body: `## Already resolved\n\n`, + body: `## Already resolved\n\n`, user: {}, }, ]); @@ -505,7 +505,7 @@ describe('DetectPotentialProblemsUseCase', () => { mockListIssueComments.mockResolvedValue([ { id: 333, - body: `## Whitespace variant\n\n`, + body: `## Whitespace variant\n\n`, user: { login: 'bot' }, }, ]); @@ -528,7 +528,7 @@ describe('DetectPotentialProblemsUseCase', () => { const updatedBody = mockUpdateComment.mock.calls[0][4]; expect(updatedBody).toContain('resolved:true'); expect(updatedBody).toContain('**Resolved** (OpenCode confirmed fixed in latest analysis)'); - expect(updatedBody).toContain('gbf-bugbot'); + expect(updatedBody).toContain('copilot-bugbot'); }); it('replaces marker in PR review comment when marker has extra whitespace', async () => { @@ -538,7 +538,7 @@ describe('DetectPotentialProblemsUseCase', () => { .mockResolvedValueOnce([ { id: 444, - body: `## PR spacey\n\n`, + body: `## PR spacey\n\n`, path: 'src/b.ts', line: 1, }, @@ -546,7 +546,7 @@ describe('DetectPotentialProblemsUseCase', () => { .mockResolvedValueOnce([ { id: 444, - body: `## PR spacey\n\n`, + body: `## PR spacey\n\n`, path: 'src/b.ts', line: 1, }, @@ -568,7 +568,7 @@ describe('DetectPotentialProblemsUseCase', () => { mockListIssueComments.mockResolvedValue([ { id: 555, - body: `## Regex id\n\n`, + body: `## Regex id\n\n`, user: {}, }, ]); @@ -601,8 +601,8 @@ describe('DetectPotentialProblemsUseCase', () => { expect(mockAddComment).toHaveBeenCalledTimes(1); const body = mockAddComment.mock.calls[0][3]; - expect(body).toContain('gbf-bugbot'); - const markerMatch = body.match(/'); @@ -611,7 +611,7 @@ describe('DetectPotentialProblemsUseCase', () => { expect(storedId).not.toContain('>'); expect(storedId).not.toContain('\n'); expect(storedId).toBe('file.ts:1:badidwithnewlinehere'); - expect(body).toMatch(//); + expect(body).toMatch(//); }); }); @@ -701,7 +701,7 @@ describe('DetectPotentialProblemsUseCase', () => { ); expect(overflowComment).toBeDefined(); expect(overflowComment).toContain('more finding(s)'); - const findingComments = bodies.filter((b) => b.includes('gbf-bugbot') && b.includes('finding_id')); + const findingComments = bodies.filter((b) => b.includes('copilot-bugbot') && b.includes('finding_id')); expect(findingComments.length).toBe(20); }); diff --git a/src/usecase/steps/commit/__tests__/notify_new_commit_on_issue_use_case.test.ts b/src/usecase/steps/commit/__tests__/notify_new_commit_on_issue_use_case.test.ts new file mode 100644 index 00000000..2aa941b1 --- /dev/null +++ b/src/usecase/steps/commit/__tests__/notify_new_commit_on_issue_use_case.test.ts @@ -0,0 +1,126 @@ +import { NotifyNewCommitOnIssueUseCase } from '../notify_new_commit_on_issue_use_case'; + +jest.mock('../../../../utils/logger', () => ({ + logInfo: jest.fn(), + logDebugInfo: jest.fn(), + logError: jest.fn(), +})); + +jest.mock('../../../../utils/list_utils', () => ({ + getRandomElement: jest.fn((arr: string[]) => arr[0]), +})); + +const mockAddComment = jest.fn(); +const mockOpenIssue = jest.fn(); +jest.mock('../../../../data/repository/issue_repository', () => ({ + IssueRepository: jest.fn().mockImplementation(() => ({ + addComment: mockAddComment, + openIssue: mockOpenIssue, + })), +})); + +const mockInvoke = jest.fn(); +jest.mock('../../common/execute_script_use_case', () => ({ + CommitPrefixBuilderUseCase: jest.fn().mockImplementation(() => ({ + invoke: mockInvoke, + })), +})); + +function baseParam(overrides: Record = {}) { + return { + owner: 'o', + repo: 'r', + issueNumber: 42, + tokens: { token: 't' }, + commit: { + branch: 'feature/42-add-login', + commits: [ + { + id: 'abc', + message: 'feat: add button', + author: { name: 'Alice', username: 'alice' }, + }, + ], + }, + commitPrefixBuilder: '', + images: { + commitReleaseGifs: ['url1'], + commitHotfixGifs: ['url2'], + commitBugfixGifs: ['url3'], + commitFeatureGifs: ['url4'], + commitDocsGifs: ['url5'], + commitChoreGifs: ['url6'], + commitAutomaticActions: ['url7'], + }, + imagesOnCommit: true, + issue: { reopenOnPush: false }, + release: { active: false }, + hotfix: { active: false }, + isFeature: true, + isBugfix: false, + isDocs: false, + isChore: false, + ...overrides, + } as unknown as Parameters[0]; +} + +describe('NotifyNewCommitOnIssueUseCase', () => { + let useCase: NotifyNewCommitOnIssueUseCase; + + beforeEach(() => { + useCase = new NotifyNewCommitOnIssueUseCase(); + mockAddComment.mockResolvedValue(undefined); + mockOpenIssue.mockResolvedValue(true); + mockInvoke.mockResolvedValue([ + { payload: { scriptResult: '' } }, + ]); + }); + + it('adds comment with commit info and returns', async () => { + const param = baseParam(); + const results = await useCase.invoke(param); + expect(mockAddComment).toHaveBeenCalledWith( + 'o', + 'r', + 42, + expect.stringContaining('Feature News'), + 't' + ); + expect(mockAddComment).toHaveBeenCalledWith( + 'o', + 'r', + 42, + expect.stringContaining('feature/42-add-login'), + 't' + ); + expect(mockAddComment).toHaveBeenCalledWith( + 'o', + 'r', + 42, + expect.stringContaining('alice'), + 't' + ); + expect(results).toEqual([]); + }); + + it('does not call openIssue when reopenOnPush is false', async () => { + const param = baseParam({ issue: { reopenOnPush: false } }); + await useCase.invoke(param); + expect(mockOpenIssue).not.toHaveBeenCalled(); + }); + + it('calls openIssue and addComment when reopenOnPush is true', async () => { + const param = baseParam({ issue: { reopenOnPush: true } }); + await useCase.invoke(param); + expect(mockOpenIssue).toHaveBeenCalledWith('o', 'r', 42, 't'); + expect(mockAddComment).toHaveBeenCalled(); + }); + + it('returns failure on error', async () => { + mockAddComment.mockRejectedValue(new Error('API error')); + const param = baseParam(); + const results = await useCase.invoke(param); + expect(results.some((r) => r.success === false)).toBe(true); + expect(results[0].errors?.length).toBeGreaterThan(0); + }); +}); diff --git a/src/usecase/steps/commit/check_changes_issue_size_use_case.ts b/src/usecase/steps/commit/check_changes_issue_size_use_case.ts index f96062d1..7ba5074a 100644 --- a/src/usecase/steps/commit/check_changes_issue_size_use_case.ts +++ b/src/usecase/steps/commit/check_changes_issue_size_use_case.ts @@ -5,6 +5,7 @@ import { IssueRepository } from "../../../data/repository/issue_repository"; import { ProjectRepository } from "../../../data/repository/project_repository"; import { PullRequestRepository } from "../../../data/repository/pull_request_repository"; import { logDebugInfo, logError, logInfo } from "../../../utils/logger"; +import { getTaskEmoji } from "../../../utils/task_emoji"; import { ParamUseCase } from "../../base/param_usecase"; export class CheckChangesIssueSizeUseCase implements ParamUseCase { @@ -16,7 +17,7 @@ export class CheckChangesIssueSizeUseCase implements ParamUseCase { - logInfo(`Executing ${this.taskId}.`); + logInfo(`${getTaskEmoji(this.taskId)} Executing ${this.taskId}.`); const result: Result[] = []; try { diff --git a/src/usecase/steps/commit/detect_potential_problems_use_case.ts b/src/usecase/steps/commit/detect_potential_problems_use_case.ts index 12e58123..a1e1a5af 100644 --- a/src/usecase/steps/commit/detect_potential_problems_use_case.ts +++ b/src/usecase/steps/commit/detect_potential_problems_use_case.ts @@ -3,6 +3,7 @@ import { Result } from "../../../data/model/result"; import { AiRepository, OPENCODE_AGENT_PLAN } from "../../../data/repository/ai_repository"; import { BUGBOT_MAX_COMMENTS } from "../../../utils/constants"; import { logDebugInfo, logError, logInfo } from "../../../utils/logger"; +import { getTaskEmoji } from "../../../utils/task_emoji"; import { ParamUseCase } from "../../base/param_usecase"; import { buildBugbotPrompt } from "./bugbot/build_bugbot_prompt"; import { deduplicateFindings } from "./bugbot/deduplicate_findings"; @@ -25,7 +26,7 @@ export class DetectPotentialProblemsUseCase implements ParamUseCase { - logInfo(`Executing ${this.taskId}.`); + logInfo(`${getTaskEmoji(this.taskId)} Executing ${this.taskId}.`); const results: Result[] = []; try { diff --git a/src/usecase/steps/commit/notify_new_commit_on_issue_use_case.ts b/src/usecase/steps/commit/notify_new_commit_on_issue_use_case.ts index f2a207bb..56d516f2 100644 --- a/src/usecase/steps/commit/notify_new_commit_on_issue_use_case.ts +++ b/src/usecase/steps/commit/notify_new_commit_on_issue_use_case.ts @@ -3,6 +3,7 @@ import { Result } from "../../../data/model/result"; import { IssueRepository } from "../../../data/repository/issue_repository"; import { getRandomElement } from "../../../utils/list_utils"; import { logDebugInfo, logError, logInfo } from "../../../utils/logger"; +import { getTaskEmoji } from "../../../utils/task_emoji"; import { ParamUseCase } from "../../base/param_usecase"; import { CommitPrefixBuilderUseCase } from "../common/execute_script_use_case"; @@ -15,7 +16,7 @@ export class NotifyNewCommitOnIssueUseCase implements ParamUseCase { - logInfo(`Executing ${this.taskId}.`) + logInfo(`${getTaskEmoji(this.taskId)} Executing ${this.taskId}.`) const result: Result[] = [] try { diff --git a/src/usecase/steps/common/check_permissions_use_case.ts b/src/usecase/steps/common/check_permissions_use_case.ts index 96ffcab2..be1a8559 100644 --- a/src/usecase/steps/common/check_permissions_use_case.ts +++ b/src/usecase/steps/common/check_permissions_use_case.ts @@ -2,6 +2,7 @@ import { Execution } from "../../../data/model/execution"; import { Result } from "../../../data/model/result"; import { ProjectRepository } from "../../../data/repository/project_repository"; import { logDebugInfo, logError, logInfo } from "../../../utils/logger"; +import { getTaskEmoji } from "../../../utils/task_emoji"; import { ParamUseCase } from "../../base/param_usecase"; export class CheckPermissionsUseCase implements ParamUseCase { @@ -10,7 +11,7 @@ export class CheckPermissionsUseCase implements ParamUseCase { - logInfo(`Executing ${this.taskId}.`); + logInfo(`${getTaskEmoji(this.taskId)} Executing ${this.taskId}.`); const result: Result[] = []; diff --git a/src/usecase/steps/common/execute_script_use_case.ts b/src/usecase/steps/common/execute_script_use_case.ts index dbcfb7d1..151a5e09 100644 --- a/src/usecase/steps/common/execute_script_use_case.ts +++ b/src/usecase/steps/common/execute_script_use_case.ts @@ -1,13 +1,14 @@ import { Execution } from "../../../data/model/execution"; import { Result } from "../../../data/model/result"; import { logDebugInfo, logError, logInfo } from "../../../utils/logger"; +import { getTaskEmoji } from "../../../utils/task_emoji"; import { ParamUseCase } from "../../base/param_usecase"; export class CommitPrefixBuilderUseCase implements ParamUseCase { taskId: string = 'CommitPrefixBuilderUseCase'; async invoke(param: Execution): Promise { - logInfo(`Executing ${this.taskId}.`) + logInfo(`${getTaskEmoji(this.taskId)} Executing ${this.taskId}.`) const result: Result[] = [] diff --git a/src/usecase/steps/common/get_hotfix_version_use_case.ts b/src/usecase/steps/common/get_hotfix_version_use_case.ts index ef166dce..91441565 100644 --- a/src/usecase/steps/common/get_hotfix_version_use_case.ts +++ b/src/usecase/steps/common/get_hotfix_version_use_case.ts @@ -3,6 +3,7 @@ import { Result } from "../../../data/model/result"; import { IssueRepository } from "../../../data/repository/issue_repository"; import { extractVersion } from "../../../utils/content_utils"; import { logError, logInfo } from "../../../utils/logger"; +import { getTaskEmoji } from "../../../utils/task_emoji"; import { ParamUseCase } from "../../base/param_usecase"; export class GetHotfixVersionUseCase implements ParamUseCase { @@ -11,7 +12,7 @@ export class GetHotfixVersionUseCase implements ParamUseCase { - logInfo(`Executing ${this.taskId}.`); + logInfo(`${getTaskEmoji(this.taskId)} Executing ${this.taskId}.`); const result: Result[] = []; diff --git a/src/usecase/steps/common/get_release_type_use_case.ts b/src/usecase/steps/common/get_release_type_use_case.ts index 3fd1c6e2..c35cee0b 100644 --- a/src/usecase/steps/common/get_release_type_use_case.ts +++ b/src/usecase/steps/common/get_release_type_use_case.ts @@ -3,6 +3,7 @@ import { Result } from "../../../data/model/result"; import { IssueRepository } from "../../../data/repository/issue_repository"; import { extractReleaseType } from "../../../utils/content_utils"; import { logError, logInfo } from "../../../utils/logger"; +import { getTaskEmoji } from "../../../utils/task_emoji"; import { ParamUseCase } from "../../base/param_usecase"; export class GetReleaseTypeUseCase implements ParamUseCase { @@ -11,7 +12,7 @@ export class GetReleaseTypeUseCase implements ParamUseCase private issueRepository = new IssueRepository(); async invoke(param: Execution): Promise { - logInfo(`Executing ${this.taskId}.`); + logInfo(`${getTaskEmoji(this.taskId)} Executing ${this.taskId}.`); const result: Result[] = []; diff --git a/src/usecase/steps/common/get_release_version_use_case.ts b/src/usecase/steps/common/get_release_version_use_case.ts index 93e9b5a2..97160c3f 100644 --- a/src/usecase/steps/common/get_release_version_use_case.ts +++ b/src/usecase/steps/common/get_release_version_use_case.ts @@ -3,6 +3,7 @@ import { Result } from "../../../data/model/result"; import { IssueRepository } from "../../../data/repository/issue_repository"; import { extractVersion } from "../../../utils/content_utils"; import { logError, logInfo } from "../../../utils/logger"; +import { getTaskEmoji } from "../../../utils/task_emoji"; import { ParamUseCase } from "../../base/param_usecase"; export class GetReleaseVersionUseCase implements ParamUseCase { @@ -11,7 +12,7 @@ export class GetReleaseVersionUseCase implements ParamUseCase { - logInfo(`Executing ${this.taskId}.`); + logInfo(`${getTaskEmoji(this.taskId)} Executing ${this.taskId}.`); const result: Result[] = []; diff --git a/src/usecase/steps/common/publish_resume_use_case.ts b/src/usecase/steps/common/publish_resume_use_case.ts index 4553d224..2eb08953 100644 --- a/src/usecase/steps/common/publish_resume_use_case.ts +++ b/src/usecase/steps/common/publish_resume_use_case.ts @@ -3,6 +3,7 @@ import { Result } from "../../../data/model/result"; import { IssueRepository } from "../../../data/repository/issue_repository"; import { getRandomElement } from "../../../utils/list_utils"; import { logError, logInfo } from "../../../utils/logger"; +import { getTaskEmoji } from "../../../utils/task_emoji"; import { ParamUseCase } from "../../base/param_usecase"; /** @@ -13,7 +14,7 @@ export class PublishResultUseCase implements ParamUseCase { private issueRepository = new IssueRepository(); async invoke(param: Execution): Promise { - logInfo(`Executing ${this.taskId}.`) + logInfo(`${getTaskEmoji(this.taskId)} Executing ${this.taskId}.`) try { /** @@ -123,7 +124,7 @@ ${footer} ${errors} -Check your project configuration, if everything is okay consider [opening an issue](https://github.com/landamessenger/git-board-flow/issues/new/choose). +Check your project configuration, if everything is okay consider [opening an issue](https://github.com/vypdev/copilot/issues/new/choose). ` } diff --git a/src/usecase/steps/common/store_configuration_use_case.ts b/src/usecase/steps/common/store_configuration_use_case.ts index 810a3024..187b6f68 100644 --- a/src/usecase/steps/common/store_configuration_use_case.ts +++ b/src/usecase/steps/common/store_configuration_use_case.ts @@ -1,6 +1,7 @@ import { Execution } from "../../../data/model/execution"; import { ConfigurationHandler } from "../../../manager/description/configuration_handler"; import { logError, logInfo } from "../../../utils/logger"; +import { getTaskEmoji } from "../../../utils/task_emoji"; import { ParamUseCase } from "../../base/param_usecase"; @@ -12,7 +13,7 @@ export class StoreConfigurationUseCase implements ParamUseCase private handler = new ConfigurationHandler(); async invoke(param: Execution): Promise { - logInfo(`Executing ${this.taskId}.`) + logInfo(`${getTaskEmoji(this.taskId)} Executing ${this.taskId}.`) try { await this.handler.update( param diff --git a/src/usecase/steps/common/update_title_use_case.ts b/src/usecase/steps/common/update_title_use_case.ts index 0439f784..b89a24ed 100644 --- a/src/usecase/steps/common/update_title_use_case.ts +++ b/src/usecase/steps/common/update_title_use_case.ts @@ -2,6 +2,7 @@ import { Execution } from "../../../data/model/execution"; import { Result } from "../../../data/model/result"; import { IssueRepository } from "../../../data/repository/issue_repository"; import { logInfo } from "../../../utils/logger"; +import { getTaskEmoji } from "../../../utils/task_emoji"; import { ParamUseCase } from "../../base/param_usecase"; export class UpdateTitleUseCase implements ParamUseCase { @@ -10,7 +11,7 @@ export class UpdateTitleUseCase implements ParamUseCase { private issueRepository = new IssueRepository(); async invoke(param: Execution): Promise { - logInfo(`Executing ${this.taskId}.`) + logInfo(`${getTaskEmoji(this.taskId)} Executing ${this.taskId}.`) const result: Result[] = [] try { diff --git a/src/usecase/steps/issue/__tests__/assign_members_to_issue_use_case.test.ts b/src/usecase/steps/issue/__tests__/assign_members_to_issue_use_case.test.ts new file mode 100644 index 00000000..26cad4eb --- /dev/null +++ b/src/usecase/steps/issue/__tests__/assign_members_to_issue_use_case.test.ts @@ -0,0 +1,94 @@ +import { AssignMemberToIssueUseCase } from '../assign_members_to_issue_use_case'; + +jest.mock('../../../../utils/logger', () => ({ + logInfo: jest.fn(), + logDebugInfo: jest.fn(), + logError: jest.fn(), +})); + +const mockGetAllMembers = jest.fn(); +const mockGetRandomMembers = jest.fn(); +jest.mock('../../../../data/repository/project_repository', () => ({ + ProjectRepository: jest.fn().mockImplementation(() => ({ + getAllMembers: mockGetAllMembers, + getRandomMembers: mockGetRandomMembers, + })), +})); + +const mockGetCurrentAssignees = jest.fn(); +const mockAssignMembersToIssue = jest.fn(); +jest.mock('../../../../data/repository/issue_repository', () => ({ + IssueRepository: jest.fn().mockImplementation(() => ({ + getCurrentAssignees: mockGetCurrentAssignees, + assignMembersToIssue: mockAssignMembersToIssue, + })), +})); + +function baseParam(overrides: Record = {}) { + return { + owner: 'o', + repo: 'r', + tokens: { token: 't' }, + issue: { number: 42, desiredAssigneesCount: 1, creator: 'alice' }, + pullRequest: { number: 42, creator: '' }, + isIssue: true, + isPullRequest: false, + ...overrides, + } as unknown as Parameters[0]; +} + +describe('AssignMemberToIssueUseCase', () => { + let useCase: AssignMemberToIssueUseCase; + + beforeEach(() => { + useCase = new AssignMemberToIssueUseCase(); + mockGetAllMembers.mockResolvedValue(['alice', 'bob']); + mockGetCurrentAssignees.mockResolvedValue([]); + mockGetRandomMembers.mockResolvedValue(['bob']); + mockAssignMembersToIssue.mockResolvedValue(['bob']); + }); + + it('assigns issue creator when creator is team member and not yet assigned', async () => { + const param = baseParam({ issue: { number: 42, desiredAssigneesCount: 1, creator: 'alice' } }); + const results = await useCase.invoke(param); + expect(mockAssignMembersToIssue).toHaveBeenCalledWith('o', 'r', 42, ['alice'], 't'); + expect(results.some((r) => r.success && r.steps?.some((s) => s.includes('alice')))).toBe(true); + }); + + it('returns success executed true when no more assignees needed after assigning creator', async () => { + const param = baseParam({ issue: { number: 42, desiredAssigneesCount: 1, creator: 'alice' } }); + mockGetCurrentAssignees.mockResolvedValue([]); + const results = await useCase.invoke(param); + expect(results.length).toBeGreaterThanOrEqual(1); + expect(results.some((r) => r.success === true)).toBe(true); + }); + + it('assigns random members when more assignees needed', async () => { + mockGetCurrentAssignees.mockResolvedValue([]); + mockGetAllMembers.mockResolvedValue(['alice', 'bob']); + const param = baseParam({ + issue: { number: 42, desiredAssigneesCount: 2, creator: '' }, + }); + mockAssignMembersToIssue.mockResolvedValue(['bob']); + const results = await useCase.invoke(param); + expect(mockGetRandomMembers).toHaveBeenCalledWith('o', 2, [], 't'); + expect(mockAssignMembersToIssue).toHaveBeenCalled(); + }); + + it('returns failure when no members found for assignment', async () => { + mockGetRandomMembers.mockResolvedValue([]); + mockGetCurrentAssignees.mockResolvedValue([]); + const param = baseParam({ + issue: { number: 42, desiredAssigneesCount: 1, creator: '' }, + }); + const results = await useCase.invoke(param); + expect(results.some((r) => !r.success && r.steps?.some((s) => s.includes('no one was found')))).toBe(true); + }); + + it('returns failure on repository error', async () => { + mockGetCurrentAssignees.mockRejectedValue(new Error('API error')); + const param = baseParam(); + const results = await useCase.invoke(param); + expect(results.some((r) => r.success === false)).toBe(true); + }); +}); diff --git a/src/usecase/steps/issue/__tests__/close_issue_after_merging_use_case.test.ts b/src/usecase/steps/issue/__tests__/close_issue_after_merging_use_case.test.ts new file mode 100644 index 00000000..34e56d6d --- /dev/null +++ b/src/usecase/steps/issue/__tests__/close_issue_after_merging_use_case.test.ts @@ -0,0 +1,72 @@ +import { CloseIssueAfterMergingUseCase } from '../close_issue_after_merging_use_case'; + +jest.mock('../../../../utils/logger', () => ({ + logInfo: jest.fn(), +})); + +const mockCloseIssue = jest.fn(); +const mockAddComment = jest.fn(); +jest.mock('../../../../data/repository/issue_repository', () => ({ + IssueRepository: jest.fn().mockImplementation(() => ({ + closeIssue: mockCloseIssue, + addComment: mockAddComment, + })), +})); + +function baseParam() { + return { + owner: 'o', + repo: 'r', + issueNumber: 42, + pullRequest: { number: 10 }, + tokens: { token: 't' }, + } as unknown as Parameters[0]; +} + +describe('CloseIssueAfterMergingUseCase', () => { + let useCase: CloseIssueAfterMergingUseCase; + + beforeEach(() => { + useCase = new CloseIssueAfterMergingUseCase(); + mockCloseIssue.mockReset(); + mockAddComment.mockReset(); + }); + + it('closes issue and adds comment when closeIssue returns true', async () => { + mockCloseIssue.mockResolvedValue(true); + mockAddComment.mockResolvedValue(undefined); + const param = baseParam(); + + const results = await useCase.invoke(param); + + expect(results).toHaveLength(1); + expect(results[0].success).toBe(true); + expect(results[0].executed).toBe(true); + expect(results[0].steps?.some((s) => s.includes('42') && s.includes('closed'))).toBe(true); + expect(mockCloseIssue).toHaveBeenCalledWith('o', 'r', 42, 't'); + expect(mockAddComment).toHaveBeenCalledWith( + 'o', + 'r', + 42, + expect.stringContaining('closed after merging #10'), + 't' + ); + }); + + it('returns success executed false when closeIssue returns false', async () => { + mockCloseIssue.mockResolvedValue(false); + const param = baseParam(); + const results = await useCase.invoke(param); + expect(results[0].success).toBe(true); + expect(results[0].executed).toBe(false); + expect(mockAddComment).not.toHaveBeenCalled(); + }); + + it('returns failure when closeIssue throws', async () => { + mockCloseIssue.mockRejectedValue(new Error('API error')); + const param = baseParam(); + const results = await useCase.invoke(param); + expect(results[0].success).toBe(false); + expect(results[0].steps?.some((s) => s.includes('42'))).toBe(true); + }); +}); diff --git a/src/usecase/steps/issue/__tests__/label_deploy_added_use_case.test.ts b/src/usecase/steps/issue/__tests__/label_deploy_added_use_case.test.ts new file mode 100644 index 00000000..5209d38f --- /dev/null +++ b/src/usecase/steps/issue/__tests__/label_deploy_added_use_case.test.ts @@ -0,0 +1,83 @@ +import { DeployAddedUseCase } from '../label_deploy_added_use_case'; + +jest.mock('../../../../utils/logger', () => ({ + logInfo: jest.fn(), + logDebugInfo: jest.fn(), + logError: jest.fn(), +})); + +const mockMoveIssueToColumn = jest.fn(); +jest.mock('../../../../data/repository/project_repository', () => ({ + ProjectRepository: jest.fn().mockImplementation(() => ({ + moveIssueToColumn: mockMoveIssueToColumn, + })), +})); + +const mockExecuteWorkflow = jest.fn(); +jest.mock('../../../../data/repository/branch_repository', () => ({ + BranchRepository: jest.fn().mockImplementation(() => ({ + executeWorkflow: mockExecuteWorkflow, + })), +})); + +function baseParam(overrides: Record = {}) { + return { + owner: 'o', + repo: 'r', + issueNumber: 42, + tokens: { token: 't' }, + issue: { + labeled: true, + labelAdded: 'deploy', + title: 'Add feature', + body: '## Changelog\n- Item', + }, + labels: { deploy: 'deploy' }, + release: { active: true, branch: 'release/1.0', version: '1.0.0' }, + hotfix: { active: false }, + workflows: { release: 'release.yml' }, + project: { + getProjects: () => [], + getProjectColumnIssueInProgress: () => 'In Progress', + }, + ...overrides, + } as unknown as Parameters[0]; +} + +describe('DeployAddedUseCase (label_deploy_added)', () => { + let useCase: DeployAddedUseCase; + + beforeEach(() => { + useCase = new DeployAddedUseCase(); + mockMoveIssueToColumn.mockResolvedValue(true); + mockExecuteWorkflow.mockResolvedValue(undefined); + }); + + it('returns executed false when labeled is false or labelAdded is not deploy', async () => { + const param = baseParam({ issue: { labeled: false, labelAdded: '', title: '', body: '' } }); + const results = await useCase.invoke(param); + expect(results.some((r) => r.executed === false)).toBe(true); + expect(mockExecuteWorkflow).not.toHaveBeenCalled(); + }); + + it('executes release workflow when release active and branch set', async () => { + const param = baseParam(); + const results = await useCase.invoke(param); + expect(mockExecuteWorkflow).toHaveBeenCalledWith( + 'o', + 'r', + 'release/1.0', + 'release.yml', + expect.any(Object), + 't' + ); + expect(results.some((r) => r.success && r.steps?.some((s) => s.includes('release')))).toBe(true); + }); + + it('returns failure when executeWorkflow throws', async () => { + mockExecuteWorkflow.mockRejectedValue(new Error('Workflow error')); + const param = baseParam(); + const results = await useCase.invoke(param); + expect(results.some((r) => r.success === false)).toBe(true); + }); +}); diff --git a/src/usecase/steps/issue/__tests__/link_issue_project_use_case.test.ts b/src/usecase/steps/issue/__tests__/link_issue_project_use_case.test.ts new file mode 100644 index 00000000..ec0f729a --- /dev/null +++ b/src/usecase/steps/issue/__tests__/link_issue_project_use_case.test.ts @@ -0,0 +1,87 @@ +import { LinkIssueProjectUseCase } from '../link_issue_project_use_case'; + +jest.mock('../../../../utils/logger', () => ({ + logInfo: jest.fn(), + logError: jest.fn(), +})); + +jest.useFakeTimers(); + +const mockGetId = jest.fn(); +jest.mock('../../../../data/repository/issue_repository', () => ({ + IssueRepository: jest.fn().mockImplementation(() => ({ + getId: mockGetId, + })), +})); + +const mockLinkContentId = jest.fn(); +const mockMoveIssueToColumn = jest.fn(); +jest.mock('../../../../data/repository/project_repository', () => ({ + ProjectRepository: jest.fn().mockImplementation(() => ({ + linkContentId: mockLinkContentId, + moveIssueToColumn: mockMoveIssueToColumn, + })), +})); + +function baseParam(overrides: Record = {}) { + return { + owner: 'o', + repo: 'r', + issue: { number: 42 }, + tokens: { token: 't' }, + project: { + getProjects: () => [{ id: 'p1', title: 'Backlog', url: 'https://github.com/org/repo/projects/1' }], + getProjectColumnIssueCreated: () => 'To Do', + }, + ...overrides, + } as unknown as Parameters[0]; +} + +describe('LinkIssueProjectUseCase', () => { + let useCase: LinkIssueProjectUseCase; + + beforeEach(() => { + useCase = new LinkIssueProjectUseCase(); + mockGetId.mockResolvedValue('issue-node-1'); + mockLinkContentId.mockResolvedValue(true); + mockMoveIssueToColumn.mockResolvedValue(true); + mockMoveIssueToColumn.mockClear(); + }); + + afterEach(() => { + jest.useRealTimers(); + }); + + it('links issue to project and moves to column when linkContentId and moveIssueToColumn succeed', async () => { + const param = baseParam(); + const promise = useCase.invoke(param); + await jest.advanceTimersByTimeAsync(10000); + const results = await promise; + expect(mockGetId).toHaveBeenCalledWith('o', 'r', 42, 't'); + expect(mockLinkContentId).toHaveBeenCalled(); + expect(mockMoveIssueToColumn).toHaveBeenCalledWith( + expect.any(Object), + 'o', + 'r', + 42, + 'To Do', + 't' + ); + expect(results.some((r) => r.success && r.steps?.some((s) => s.includes('Backlog')))).toBe(true); + }); + + it('returns result with executed false when linkContentId returns false', async () => { + mockLinkContentId.mockResolvedValue(false); + const param = baseParam(); + const results = await useCase.invoke(param); + expect(mockMoveIssueToColumn).not.toHaveBeenCalled(); + expect(results.length).toBeGreaterThanOrEqual(0); + }); + + it('returns failure on error', async () => { + mockGetId.mockRejectedValue(new Error('API error')); + const param = baseParam(); + const results = await useCase.invoke(param); + expect(results.some((r) => r.success === false)).toBe(true); + }); +}); diff --git a/src/usecase/steps/issue/__tests__/move_issue_to_in_progress_use_case.test.ts b/src/usecase/steps/issue/__tests__/move_issue_to_in_progress_use_case.test.ts new file mode 100644 index 00000000..61db23a7 --- /dev/null +++ b/src/usecase/steps/issue/__tests__/move_issue_to_in_progress_use_case.test.ts @@ -0,0 +1,60 @@ +import { MoveIssueToInProgressUseCase } from '../move_issue_to_in_progress'; + +jest.mock('../../../../utils/logger', () => ({ + logInfo: jest.fn(), + logError: jest.fn(), +})); + +const mockMoveIssueToColumn = jest.fn(); +jest.mock('../../../../data/repository/project_repository', () => ({ + ProjectRepository: jest.fn().mockImplementation(() => ({ + moveIssueToColumn: mockMoveIssueToColumn, + })), +})); + +function baseParam(overrides: Record = {}) { + return { + owner: 'o', + repo: 'r', + issueNumber: 42, + tokens: { token: 't' }, + project: { + getProjects: () => [{ id: 'p1', title: 'Backlog', url: 'https://github.com/org/repo/projects/1' }], + getProjectColumnIssueInProgress: () => 'In Progress', + }, + ...overrides, + } as unknown as Parameters[0]; +} + +describe('MoveIssueToInProgressUseCase', () => { + let useCase: MoveIssueToInProgressUseCase; + + beforeEach(() => { + useCase = new MoveIssueToInProgressUseCase(); + mockMoveIssueToColumn.mockResolvedValue(true); + }); + + it('moves issue to in-progress column and returns success', async () => { + const param = baseParam(); + const results = await useCase.invoke(param); + expect(mockMoveIssueToColumn).toHaveBeenCalledWith( + expect.any(Object), + 'o', + 'r', + 42, + 'In Progress', + 't' + ); + expect(results).toHaveLength(1); + expect(results[0].success).toBe(true); + expect(results[0].steps?.some((s) => s.includes('In Progress'))).toBe(true); + }); + + it('returns failure when moveIssueToColumn throws', async () => { + mockMoveIssueToColumn.mockRejectedValue(new Error('API error')); + const param = baseParam(); + const results = await useCase.invoke(param); + expect(results[0].success).toBe(false); + expect(results[0].errors?.length).toBeGreaterThan(0); + }); +}); diff --git a/src/usecase/steps/issue/__tests__/prepare_branches_use_case.test.ts b/src/usecase/steps/issue/__tests__/prepare_branches_use_case.test.ts new file mode 100644 index 00000000..0ba4af0c --- /dev/null +++ b/src/usecase/steps/issue/__tests__/prepare_branches_use_case.test.ts @@ -0,0 +1,114 @@ +import * as core from '@actions/core'; +import { PrepareBranchesUseCase } from '../prepare_branches_use_case'; + +jest.mock('../../../../utils/logger', () => ({ + logInfo: jest.fn(), + logDebugInfo: jest.fn(), + logError: jest.fn(), +})); + +jest.mock('@actions/core', () => ({ + setFailed: jest.fn(), +})); + +const mockFetchRemoteBranches = jest.fn(); +const mockGetListOfBranches = jest.fn(); +const mockManageBranches = jest.fn(); +jest.mock('../../../../data/repository/branch_repository', () => ({ + BranchRepository: jest.fn().mockImplementation(() => ({ + fetchRemoteBranches: mockFetchRemoteBranches, + getListOfBranches: mockGetListOfBranches, + manageBranches: mockManageBranches, + })), +})); + +const mockMoveIssueToColumn = jest.fn(); +jest.mock('../../../../data/repository/project_repository', () => ({ + ProjectRepository: jest.fn().mockImplementation(() => ({ + moveIssueToColumn: mockMoveIssueToColumn, + })), +})); + +function baseParam(overrides: Record = {}) { + return { + owner: 'o', + repo: 'r', + issueNumber: 42, + tokens: { token: 't' }, + issue: { title: 'Add login feature' }, + labels: { isMandatoryBranchedLabel: true }, + managementBranch: 'feature', + branches: { + development: 'develop', + defaultBranch: 'main', + featureTree: 'feature', + bugfixTree: 'bugfix', + hotfixTree: 'hotfix', + main: 'main', + }, + release: { active: false }, + hotfix: { active: false }, + commitPrefixBuilder: '', + currentConfiguration: {}, + project: { getProjects: () => [], getProjectColumnIssueInProgress: () => '' }, + ...overrides, + } as unknown as Parameters[0]; +} + +describe('PrepareBranchesUseCase', () => { + let useCase: PrepareBranchesUseCase; + + beforeEach(() => { + jest.useFakeTimers(); + useCase = new PrepareBranchesUseCase(); + mockFetchRemoteBranches.mockResolvedValue(undefined); + mockGetListOfBranches.mockResolvedValue(['develop', 'main']); + mockMoveIssueToColumn.mockResolvedValue(true); + mockManageBranches.mockResolvedValue([ + { + id: 'PrepareBranchesUseCase', + success: true, + executed: true, + payload: { + newBranchName: 'feature/42-add-login-feature', + newBranchUrl: 'https://github.com/o/r/tree/feature/42-add-login-feature', + baseBranchName: 'develop', + baseBranchUrl: 'https://github.com/o/r/tree/develop', + }, + }, + ]); + }); + + afterEach(() => { + jest.useRealTimers(); + }); + + it('returns failure when issue title is empty and not mandatory branched label', async () => { + const param = baseParam({ + issue: { title: '' }, + labels: { isMandatoryBranchedLabel: false }, + }); + const results = await useCase.invoke(param); + expect(core.setFailed).toHaveBeenCalledWith('Issue title not available.'); + expect(results.some((r) => r.success === false)).toBe(true); + }); + + it('fetches remote branches and gets list of branches', async () => { + const param = baseParam(); + const promise = useCase.invoke(param); + await jest.advanceTimersByTimeAsync(10000); + await promise; + expect(mockFetchRemoteBranches).toHaveBeenCalled(); + expect(mockGetListOfBranches).toHaveBeenCalledWith('o', 'r', 't'); + }); + + it('calls manageBranches and returns results when not release/hotfix', async () => { + const param = baseParam(); + const promise = useCase.invoke(param); + await jest.advanceTimersByTimeAsync(10000); + const results = await promise; + expect(mockManageBranches).toHaveBeenCalled(); + expect(results.length).toBeGreaterThan(0); + expect(results.some((r) => r.success === true)).toBe(true); + }); +}); diff --git a/src/usecase/steps/issue/__tests__/remove_issue_branches_use_case.test.ts b/src/usecase/steps/issue/__tests__/remove_issue_branches_use_case.test.ts new file mode 100644 index 00000000..d99d7c69 --- /dev/null +++ b/src/usecase/steps/issue/__tests__/remove_issue_branches_use_case.test.ts @@ -0,0 +1,62 @@ +import { RemoveIssueBranchesUseCase } from '../remove_issue_branches_use_case'; + +jest.mock('../../../../utils/logger', () => ({ + logInfo: jest.fn(), + logDebugInfo: jest.fn(), + logError: jest.fn(), +})); + +const mockGetListOfBranches = jest.fn(); +const mockRemoveBranch = jest.fn(); +jest.mock('../../../../data/repository/branch_repository', () => ({ + BranchRepository: jest.fn().mockImplementation(() => ({ + getListOfBranches: mockGetListOfBranches, + removeBranch: mockRemoveBranch, + })), +})); + +function baseParam(overrides: Record = {}) { + return { + owner: 'o', + repo: 'r', + issueNumber: 42, + tokens: { token: 't' }, + branches: { featureTree: 'feature', bugfixTree: 'bugfix', hotfixTree: 'hotfix' }, + previousConfiguration: undefined, + ...overrides, + } as unknown as Parameters[0]; +} + +describe('RemoveIssueBranchesUseCase', () => { + let useCase: RemoveIssueBranchesUseCase; + + beforeEach(() => { + useCase = new RemoveIssueBranchesUseCase(); + mockGetListOfBranches.mockResolvedValue(['develop', 'main', 'feature/42-old-name']); + mockRemoveBranch.mockResolvedValue(true); + mockRemoveBranch.mockClear(); + }); + + it('removes matching branch for issue and returns success', async () => { + const param = baseParam(); + const results = await useCase.invoke(param); + expect(mockGetListOfBranches).toHaveBeenCalledWith('o', 'r', 't'); + expect(mockRemoveBranch).toHaveBeenCalledWith('o', 'r', 'feature/42-old-name', 't'); + expect(results.some((r) => r.success && r.steps?.some((s) => s.includes('feature/42-old-name')))).toBe(true); + }); + + it('returns no removal when no matching branch prefix', async () => { + mockGetListOfBranches.mockResolvedValue(['develop', 'main']); + const param = baseParam(); + const results = await useCase.invoke(param); + expect(mockRemoveBranch).not.toHaveBeenCalled(); + expect(results).toHaveLength(0); + }); + + it('returns failure on error', async () => { + mockGetListOfBranches.mockRejectedValue(new Error('API error')); + const param = baseParam(); + const results = await useCase.invoke(param); + expect(results.some((r) => r.success === false)).toBe(true); + }); +}); diff --git a/src/usecase/steps/issue/__tests__/remove_not_needed_branches_use_case.test.ts b/src/usecase/steps/issue/__tests__/remove_not_needed_branches_use_case.test.ts new file mode 100644 index 00000000..8e8457de --- /dev/null +++ b/src/usecase/steps/issue/__tests__/remove_not_needed_branches_use_case.test.ts @@ -0,0 +1,69 @@ +import * as core from '@actions/core'; +import { RemoveNotNeededBranchesUseCase } from '../remove_not_needed_branches_use_case'; + +jest.mock('../../../../utils/logger', () => ({ + logInfo: jest.fn(), + logError: jest.fn(), +})); + +jest.mock('@actions/core', () => ({ + setFailed: jest.fn(), +})); + +const mockFormatBranchName = jest.fn(); +const mockGetListOfBranches = jest.fn(); +const mockRemoveBranch = jest.fn(); +jest.mock('../../../../data/repository/branch_repository', () => ({ + BranchRepository: jest.fn().mockImplementation(() => ({ + formatBranchName: mockFormatBranchName, + getListOfBranches: mockGetListOfBranches, + removeBranch: mockRemoveBranch, + })), +})); + +function baseParam(overrides: Record = {}) { + return { + owner: 'o', + repo: 'r', + issueNumber: 42, + tokens: { token: 't' }, + issue: { title: 'Add login' }, + managementBranch: 'feature', + branches: { featureTree: 'feature', bugfixTree: 'bugfix' }, + ...overrides, + } as unknown as Parameters[0]; +} + +describe('RemoveNotNeededBranchesUseCase', () => { + let useCase: RemoveNotNeededBranchesUseCase; + + beforeEach(() => { + useCase = new RemoveNotNeededBranchesUseCase(); + mockFormatBranchName.mockReturnValue('add-login'); + mockGetListOfBranches.mockResolvedValue(['feature/42-add-login', 'bugfix/42-old-name']); + mockRemoveBranch.mockResolvedValue(true); + }); + + it('calls setFailed and returns when issue title is empty', async () => { + const param = baseParam({ issue: { title: '' } }); + const results = await useCase.invoke(param); + expect(core.setFailed).toHaveBeenCalledWith('Issue title not available.'); + expect(results.some((r) => r.steps?.some((s) => s.includes('title was not found')))).toBe(true); + }); + + it('removes branches that do not match final branch name', async () => { + const param = baseParam(); + const results = await useCase.invoke(param); + expect(mockFormatBranchName).toHaveBeenCalledWith('Add login', 42); + expect(mockGetListOfBranches).toHaveBeenCalledWith('o', 'r', 't'); + expect(mockRemoveBranch).toHaveBeenCalled(); + expect(results.length).toBeGreaterThanOrEqual(0); + }); + + it('returns failure on error', async () => { + mockGetListOfBranches.mockRejectedValue(new Error('API error')); + const param = baseParam(); + const results = await useCase.invoke(param); + expect(results.some((r) => r.success === false)).toBe(true); + }); +}); diff --git a/src/usecase/steps/issue/assign_members_to_issue_use_case.ts b/src/usecase/steps/issue/assign_members_to_issue_use_case.ts index d67d49c1..06cdd2df 100644 --- a/src/usecase/steps/issue/assign_members_to_issue_use_case.ts +++ b/src/usecase/steps/issue/assign_members_to_issue_use_case.ts @@ -3,6 +3,7 @@ import { Result } from "../../../data/model/result"; import { IssueRepository } from "../../../data/repository/issue_repository"; import { ProjectRepository } from "../../../data/repository/project_repository"; import { logDebugInfo, logError, logInfo } from "../../../utils/logger"; +import { getTaskEmoji } from "../../../utils/task_emoji"; import { ParamUseCase } from "../../base/param_usecase"; export class AssignMemberToIssueUseCase implements ParamUseCase { @@ -12,7 +13,7 @@ export class AssignMemberToIssueUseCase implements ParamUseCase { - logInfo(`Executing ${this.taskId}.`); + logInfo(`${getTaskEmoji(this.taskId)} Executing ${this.taskId}.`); const desiredAssigneesCount = param.isIssue ? param.issue.desiredAssigneesCount : param.pullRequest.desiredAssigneesCount; diff --git a/src/usecase/steps/issue/assign_reviewers_to_issue_use_case.ts b/src/usecase/steps/issue/assign_reviewers_to_issue_use_case.ts index bf109442..e04e8815 100644 --- a/src/usecase/steps/issue/assign_reviewers_to_issue_use_case.ts +++ b/src/usecase/steps/issue/assign_reviewers_to_issue_use_case.ts @@ -4,6 +4,7 @@ import { IssueRepository } from "../../../data/repository/issue_repository"; import { ProjectRepository } from "../../../data/repository/project_repository"; import { PullRequestRepository } from "../../../data/repository/pull_request_repository"; import { logDebugInfo, logError, logInfo } from "../../../utils/logger"; +import { getTaskEmoji } from "../../../utils/task_emoji"; import { ParamUseCase } from "../../base/param_usecase"; export class AssignReviewersToIssueUseCase implements ParamUseCase { @@ -14,7 +15,7 @@ export class AssignReviewersToIssueUseCase implements ParamUseCase { - logInfo(`Executing ${this.taskId}.`) + logInfo(`${getTaskEmoji(this.taskId)} Executing ${this.taskId}.`) const desiredReviewersCount = param.pullRequest.desiredReviewersCount const number = param.pullRequest.number diff --git a/src/usecase/steps/issue/check_priority_issue_size_use_case.ts b/src/usecase/steps/issue/check_priority_issue_size_use_case.ts index cc80ba0b..28f4dec7 100644 --- a/src/usecase/steps/issue/check_priority_issue_size_use_case.ts +++ b/src/usecase/steps/issue/check_priority_issue_size_use_case.ts @@ -2,6 +2,7 @@ import { Execution } from "../../../data/model/execution"; import { Result } from "../../../data/model/result"; import { ProjectRepository } from "../../../data/repository/project_repository"; import { logDebugInfo, logError, logInfo } from "../../../utils/logger"; +import { getTaskEmoji } from "../../../utils/task_emoji"; import { ParamUseCase } from "../../base/param_usecase"; export class CheckPriorityIssueSizeUseCase implements ParamUseCase { @@ -10,7 +11,7 @@ export class CheckPriorityIssueSizeUseCase implements ParamUseCase { - logInfo(`Executing ${this.taskId}.`) + logInfo(`${getTaskEmoji(this.taskId)} Executing ${this.taskId}.`) const result: Result[] = [] try { diff --git a/src/usecase/steps/issue/close_issue_after_merging_use_case.ts b/src/usecase/steps/issue/close_issue_after_merging_use_case.ts index 6de926fc..aebeefd3 100644 --- a/src/usecase/steps/issue/close_issue_after_merging_use_case.ts +++ b/src/usecase/steps/issue/close_issue_after_merging_use_case.ts @@ -2,6 +2,7 @@ import { Execution } from "../../../data/model/execution"; import { Result } from "../../../data/model/result"; import { IssueRepository } from "../../../data/repository/issue_repository"; import { logInfo } from "../../../utils/logger"; +import { getTaskEmoji } from "../../../utils/task_emoji"; import { ParamUseCase } from "../../base/param_usecase"; export class CloseIssueAfterMergingUseCase implements ParamUseCase { @@ -10,7 +11,7 @@ export class CloseIssueAfterMergingUseCase implements ParamUseCase { - logInfo(`Executing ${this.taskId}.`) + logInfo(`${getTaskEmoji(this.taskId)} Executing ${this.taskId}.`) const result: Result[] = [] try { diff --git a/src/usecase/steps/issue/close_not_allowed_issue_use_case.ts b/src/usecase/steps/issue/close_not_allowed_issue_use_case.ts index c9604b92..aabe5dc6 100644 --- a/src/usecase/steps/issue/close_not_allowed_issue_use_case.ts +++ b/src/usecase/steps/issue/close_not_allowed_issue_use_case.ts @@ -2,6 +2,7 @@ import { Execution } from "../../../data/model/execution"; import { Result } from "../../../data/model/result"; import { IssueRepository } from "../../../data/repository/issue_repository"; import { logInfo } from "../../../utils/logger"; +import { getTaskEmoji } from "../../../utils/task_emoji"; import { ParamUseCase } from "../../base/param_usecase"; export class CloseNotAllowedIssueUseCase implements ParamUseCase { @@ -10,7 +11,7 @@ export class CloseNotAllowedIssueUseCase implements ParamUseCase { - logInfo(`Executing ${this.taskId}.`) + logInfo(`${getTaskEmoji(this.taskId)} Executing ${this.taskId}.`) const result: Result[] = [] try { diff --git a/src/usecase/steps/issue/label_deploy_added_use_case.ts b/src/usecase/steps/issue/label_deploy_added_use_case.ts index 4bf8ee1a..022dbda3 100644 --- a/src/usecase/steps/issue/label_deploy_added_use_case.ts +++ b/src/usecase/steps/issue/label_deploy_added_use_case.ts @@ -3,6 +3,7 @@ import { Result } from "../../../data/model/result"; import { BranchRepository } from "../../../data/repository/branch_repository"; import { extractChangelogUpToAdditionalContext, injectJsonAsMarkdownBlock } from "../../../utils/content_utils"; import { logDebugInfo, logError, logInfo } from "../../../utils/logger"; +import { getTaskEmoji } from "../../../utils/task_emoji"; import { ParamUseCase } from "../../base/param_usecase"; import { MoveIssueToInProgressUseCase } from "./move_issue_to_in_progress"; @@ -12,7 +13,7 @@ export class DeployAddedUseCase implements ParamUseCase { private branchRepository = new BranchRepository(); async invoke(param: Execution): Promise { - logInfo(`Executing ${this.taskId}.`) + logInfo(`${getTaskEmoji(this.taskId)} Executing ${this.taskId}.`) const result: Result[] = [] try { diff --git a/src/usecase/steps/issue/label_deployed_added_use_case.ts b/src/usecase/steps/issue/label_deployed_added_use_case.ts index 9ba9577d..6e23956c 100644 --- a/src/usecase/steps/issue/label_deployed_added_use_case.ts +++ b/src/usecase/steps/issue/label_deployed_added_use_case.ts @@ -1,13 +1,14 @@ import { Execution } from "../../../data/model/execution"; import { Result } from "../../../data/model/result"; import { logDebugInfo, logError, logInfo } from "../../../utils/logger"; +import { getTaskEmoji } from "../../../utils/task_emoji"; import { ParamUseCase } from "../../base/param_usecase"; export class DeployedAddedUseCase implements ParamUseCase { taskId: string = 'DeployedAddedUseCase'; async invoke(param: Execution): Promise { - logInfo(`Executing ${this.taskId}.`) + logInfo(`${getTaskEmoji(this.taskId)} Executing ${this.taskId}.`) const result: Result[] = [] try { diff --git a/src/usecase/steps/issue/link_issue_project_use_case.ts b/src/usecase/steps/issue/link_issue_project_use_case.ts index 1541314e..918d5c1c 100644 --- a/src/usecase/steps/issue/link_issue_project_use_case.ts +++ b/src/usecase/steps/issue/link_issue_project_use_case.ts @@ -3,6 +3,7 @@ import { Result } from "../../../data/model/result"; import { IssueRepository } from "../../../data/repository/issue_repository"; import { ProjectRepository } from "../../../data/repository/project_repository"; import { logError, logInfo } from "../../../utils/logger"; +import { getTaskEmoji } from "../../../utils/task_emoji"; import { ParamUseCase } from "../../base/param_usecase"; export class LinkIssueProjectUseCase implements ParamUseCase { @@ -12,7 +13,7 @@ export class LinkIssueProjectUseCase implements ParamUseCase { - logInfo(`Executing ${this.taskId}.`) + logInfo(`${getTaskEmoji(this.taskId)} Executing ${this.taskId}.`) const result: Result[] = [] diff --git a/src/usecase/steps/issue/move_issue_to_in_progress.ts b/src/usecase/steps/issue/move_issue_to_in_progress.ts index f5d40eac..edfa7c25 100644 --- a/src/usecase/steps/issue/move_issue_to_in_progress.ts +++ b/src/usecase/steps/issue/move_issue_to_in_progress.ts @@ -2,6 +2,7 @@ import { Execution } from "../../../data/model/execution"; import { Result } from "../../../data/model/result"; import { ProjectRepository } from "../../../data/repository/project_repository"; import { logError, logInfo } from "../../../utils/logger"; +import { getTaskEmoji } from "../../../utils/task_emoji"; import { ParamUseCase } from "../../base/param_usecase"; export class MoveIssueToInProgressUseCase implements ParamUseCase { @@ -10,7 +11,7 @@ export class MoveIssueToInProgressUseCase implements ParamUseCase { - logInfo(`Executing ${this.taskId}.`) + logInfo(`${getTaskEmoji(this.taskId)} Executing ${this.taskId}.`) const result: Result[] = [] const columnName = param.project.getProjectColumnIssueInProgress(); diff --git a/src/usecase/steps/issue/prepare_branches_use_case.ts b/src/usecase/steps/issue/prepare_branches_use_case.ts index ea77a876..9fcff11c 100644 --- a/src/usecase/steps/issue/prepare_branches_use_case.ts +++ b/src/usecase/steps/issue/prepare_branches_use_case.ts @@ -3,6 +3,7 @@ import { Execution } from "../../../data/model/execution"; import { Result } from "../../../data/model/result"; import { BranchRepository } from "../../../data/repository/branch_repository"; import { logDebugInfo, logError, logInfo } from "../../../utils/logger"; +import { getTaskEmoji } from "../../../utils/task_emoji"; import { ParamUseCase } from "../../base/param_usecase"; import { CommitPrefixBuilderUseCase } from "../common/execute_script_use_case"; import { MoveIssueToInProgressUseCase } from "./move_issue_to_in_progress"; @@ -13,7 +14,7 @@ export class PrepareBranchesUseCase implements ParamUseCase private branchRepository = new BranchRepository(); async invoke(param: Execution): Promise { - logInfo(`Executing ${this.taskId}.`) + logInfo(`${getTaskEmoji(this.taskId)} Executing ${this.taskId}.`) const result: Result[] = [] try { diff --git a/src/usecase/steps/issue/remove_issue_branches_use_case.ts b/src/usecase/steps/issue/remove_issue_branches_use_case.ts index 2cabead0..851b982f 100644 --- a/src/usecase/steps/issue/remove_issue_branches_use_case.ts +++ b/src/usecase/steps/issue/remove_issue_branches_use_case.ts @@ -2,6 +2,7 @@ import { Execution } from "../../../data/model/execution"; import { Result } from "../../../data/model/result"; import { BranchRepository } from "../../../data/repository/branch_repository"; import { logDebugInfo, logError, logInfo } from "../../../utils/logger"; +import { getTaskEmoji } from "../../../utils/task_emoji"; import { ParamUseCase } from "../../base/param_usecase"; /** @@ -12,7 +13,7 @@ export class RemoveIssueBranchesUseCase implements ParamUseCase { - logInfo(`Executing ${this.taskId}.`) + logInfo(`${getTaskEmoji(this.taskId)} Executing ${this.taskId}.`) const results: Result[] = [] try { diff --git a/src/usecase/steps/issue/remove_not_needed_branches_use_case.ts b/src/usecase/steps/issue/remove_not_needed_branches_use_case.ts index 2b60a8a9..244030a3 100644 --- a/src/usecase/steps/issue/remove_not_needed_branches_use_case.ts +++ b/src/usecase/steps/issue/remove_not_needed_branches_use_case.ts @@ -3,6 +3,7 @@ import { Execution } from "../../../data/model/execution"; import { Result } from "../../../data/model/result"; import { BranchRepository } from "../../../data/repository/branch_repository"; import { logError, logInfo } from "../../../utils/logger"; +import { getTaskEmoji } from "../../../utils/task_emoji"; import { ParamUseCase } from "../../base/param_usecase"; export class RemoveNotNeededBranchesUseCase implements ParamUseCase { @@ -11,7 +12,7 @@ export class RemoveNotNeededBranchesUseCase implements ParamUseCase { - logInfo(`Executing ${this.taskId}.`) + logInfo(`${getTaskEmoji(this.taskId)} Executing ${this.taskId}.`) const result: Result[] = [] try { diff --git a/src/usecase/steps/issue/update_issue_type_use_case.ts b/src/usecase/steps/issue/update_issue_type_use_case.ts index 0d8a7b70..48d81cb4 100644 --- a/src/usecase/steps/issue/update_issue_type_use_case.ts +++ b/src/usecase/steps/issue/update_issue_type_use_case.ts @@ -2,6 +2,7 @@ import { Execution } from "../../../data/model/execution"; import { Result } from "../../../data/model/result"; import { IssueRepository } from "../../../data/repository/issue_repository"; import { logError, logInfo } from "../../../utils/logger"; +import { getTaskEmoji } from "../../../utils/task_emoji"; import { ParamUseCase } from "../../base/param_usecase"; export class UpdateIssueTypeUseCase implements ParamUseCase { @@ -10,7 +11,7 @@ export class UpdateIssueTypeUseCase implements ParamUseCase private issueRepository = new IssueRepository(); async invoke(param: Execution): Promise { - logInfo(`Executing ${this.taskId}.`) + logInfo(`${getTaskEmoji(this.taskId)} Executing ${this.taskId}.`) const result: Result[] = [] diff --git a/src/usecase/steps/issue_comment/check_issue_comment_language_use_case.ts b/src/usecase/steps/issue_comment/check_issue_comment_language_use_case.ts index fff19a5b..a51997eb 100644 --- a/src/usecase/steps/issue_comment/check_issue_comment_language_use_case.ts +++ b/src/usecase/steps/issue_comment/check_issue_comment_language_use_case.ts @@ -8,6 +8,7 @@ import { } from "../../../data/repository/ai_repository"; import { IssueRepository } from "../../../data/repository/issue_repository"; import { logInfo } from "../../../utils/logger"; +import { getTaskEmoji } from "../../../utils/task_emoji"; import { ParamUseCase } from "../../base/param_usecase"; export class CheckIssueCommentLanguageUseCase implements ParamUseCase { @@ -20,7 +21,7 @@ If you'd like this comment to be translated again, please delete the entire comm -->`; async invoke(param: Execution): Promise { - logInfo(`Executing ${this.taskId}.`) + logInfo(`${getTaskEmoji(this.taskId)} Executing ${this.taskId}.`) const results: Result[] = [] diff --git a/src/usecase/steps/pull_request/__tests__/link_pull_request_issue_use_case.test.ts b/src/usecase/steps/pull_request/__tests__/link_pull_request_issue_use_case.test.ts new file mode 100644 index 00000000..4725c8a2 --- /dev/null +++ b/src/usecase/steps/pull_request/__tests__/link_pull_request_issue_use_case.test.ts @@ -0,0 +1,77 @@ +import * as github from '@actions/github'; +import { LinkPullRequestIssueUseCase } from '../link_pull_request_issue_use_case'; + +jest.mock('../../../../utils/logger', () => ({ + logInfo: jest.fn(), + logError: jest.fn(), +})); + +jest.useFakeTimers(); + +const mockIsLinked = jest.fn(); +const mockUpdateBaseBranch = jest.fn(); +const mockUpdateDescription = jest.fn(); +jest.mock('../../../../data/repository/pull_request_repository', () => ({ + PullRequestRepository: jest.fn().mockImplementation(() => ({ + isLinked: mockIsLinked, + updateBaseBranch: mockUpdateBaseBranch, + updateDescription: mockUpdateDescription, + })), +})); + +function baseParam() { + return { + owner: 'o', + repo: 'r', + issueNumber: 42, + pullRequest: { number: 10, base: 'develop', body: 'PR body' }, + branches: { defaultBranch: 'main' }, + tokens: { token: 't' }, + } as unknown as Parameters[0]; +} + +describe('LinkPullRequestIssueUseCase', () => { + let useCase: LinkPullRequestIssueUseCase; + + beforeEach(() => { + useCase = new LinkPullRequestIssueUseCase(); + (github.context as { payload?: { pull_request?: { html_url?: string } } }).payload = { + pull_request: { html_url: 'https://github.com/o/r/pull/10' }, + }; + mockIsLinked.mockResolvedValue(false); + mockUpdateBaseBranch.mockResolvedValue(undefined); + mockUpdateDescription.mockResolvedValue(undefined); + mockUpdateBaseBranch.mockClear(); + }); + + afterEach(() => { + jest.useRealTimers(); + }); + + it('updates base branch, description, waits, reverts base and description when PR is not linked', async () => { + const param = baseParam(); + const promise = useCase.invoke(param); + await jest.advanceTimersByTimeAsync(20000); + const results = await promise; + expect(mockIsLinked).toHaveBeenCalledWith('https://github.com/o/r/pull/10'); + expect(mockUpdateBaseBranch).toHaveBeenCalledWith('o', 'r', 10, 'main', 't'); + expect(mockUpdateDescription).toHaveBeenCalledWith('o', 'r', 10, expect.stringContaining('Resolves #42'), 't'); + expect(mockUpdateBaseBranch).toHaveBeenCalledWith('o', 'r', 10, 'develop', 't'); + expect(results.some((r) => r.success && r.steps?.length)).toBe(true); + }); + + it('returns without actions when isLinked returns true', async () => { + mockIsLinked.mockResolvedValue(true); + const param = baseParam(); + const results = await useCase.invoke(param); + expect(mockUpdateBaseBranch).not.toHaveBeenCalled(); + expect(results).toHaveLength(0); + }); + + it('returns failure on error', async () => { + mockIsLinked.mockRejectedValue(new Error('API error')); + const param = baseParam(); + const results = await useCase.invoke(param); + expect(results.some((r) => r.success === false)).toBe(true); + }); +}); diff --git a/src/usecase/steps/pull_request/__tests__/link_pull_request_project_use_case.test.ts b/src/usecase/steps/pull_request/__tests__/link_pull_request_project_use_case.test.ts new file mode 100644 index 00000000..50c8932f --- /dev/null +++ b/src/usecase/steps/pull_request/__tests__/link_pull_request_project_use_case.test.ts @@ -0,0 +1,77 @@ +import { LinkPullRequestProjectUseCase } from '../link_pull_request_project_use_case'; + +jest.mock('../../../../utils/logger', () => ({ + logInfo: jest.fn(), + logError: jest.fn(), +})); + +const mockLinkContentId = jest.fn(); +const mockMoveIssueToColumn = jest.fn(); +jest.mock('../../../../data/repository/project_repository', () => ({ + ProjectRepository: jest.fn().mockImplementation(() => ({ + linkContentId: mockLinkContentId, + moveIssueToColumn: mockMoveIssueToColumn, + })), +})); + +function baseParam(overrides: Record = {}) { + return { + owner: 'o', + repo: 'r', + pullRequest: { number: 10, id: 'pr-node-1' }, + tokens: { token: 't' }, + project: { + getProjects: () => [{ id: 'p1', title: 'Backlog', url: 'https://github.com/org/repo/projects/1' }], + getProjectColumnPullRequestCreated: () => 'To Do', + }, + ...overrides, + } as unknown as Parameters[0]; +} + +describe('LinkPullRequestProjectUseCase', () => { + let useCase: LinkPullRequestProjectUseCase; + + beforeEach(() => { + jest.useFakeTimers(); + useCase = new LinkPullRequestProjectUseCase(); + mockLinkContentId.mockResolvedValue(true); + mockMoveIssueToColumn.mockResolvedValue(true); + }); + + afterEach(() => { + jest.useRealTimers(); + }); + + it('links PR to project and moves to column', async () => { + const param = baseParam(); + const promise = useCase.invoke(param); + await jest.advanceTimersByTimeAsync(10000); + const results = await promise; + expect(mockLinkContentId).toHaveBeenCalledWith(expect.any(Object), 'pr-node-1', 't'); + expect(mockMoveIssueToColumn).toHaveBeenCalledWith( + expect.any(Object), + 'o', + 'r', + 10, + 'To Do', + 't' + ); + expect(results.some((r) => r.success && r.steps?.some((s) => s.includes('Backlog')))).toBe(true); + }); + + it('returns failure when moveIssueToColumn returns false', async () => { + mockMoveIssueToColumn.mockResolvedValue(false); + const param = baseParam(); + const promise = useCase.invoke(param); + await jest.advanceTimersByTimeAsync(10000); + const results = await promise; + expect(results.some((r) => r.success === false && r.steps?.some((s) => s.includes('error moving')))).toBe(true); + }); + + it('returns failure on error', async () => { + mockLinkContentId.mockRejectedValue(new Error('API error')); + const param = baseParam(); + const results = await useCase.invoke(param); + expect(results.some((r) => r.success === false)).toBe(true); + }); +}); diff --git a/src/usecase/steps/pull_request/__tests__/update_pull_request_description_use_case.test.ts b/src/usecase/steps/pull_request/__tests__/update_pull_request_description_use_case.test.ts new file mode 100644 index 00000000..dcdf496c --- /dev/null +++ b/src/usecase/steps/pull_request/__tests__/update_pull_request_description_use_case.test.ts @@ -0,0 +1,98 @@ +import { UpdatePullRequestDescriptionUseCase } from '../update_pull_request_description_use_case'; +import { Ai } from '../../../../data/model/ai'; + +jest.mock('../../../../utils/logger', () => ({ + logDebugInfo: jest.fn(), + logError: jest.fn(), +})); + +const mockGetIssueDescription = jest.fn(); +jest.mock('../../../../data/repository/issue_repository', () => ({ + IssueRepository: jest.fn().mockImplementation(() => ({ + getIssueDescription: mockGetIssueDescription, + })), +})); + +const mockGetAllMembers = jest.fn(); +jest.mock('../../../../data/repository/project_repository', () => ({ + ProjectRepository: jest.fn().mockImplementation(() => ({ + getAllMembers: mockGetAllMembers, + })), +})); + +const mockAskAgent = jest.fn(); +jest.mock('../../../../data/repository/ai_repository', () => ({ + AiRepository: jest.fn().mockImplementation(() => ({ + askAgent: mockAskAgent, + })), + OPENCODE_AGENT_PLAN: 'plan', +})); + +const mockUpdateDescription = jest.fn(); +jest.mock('../../../../data/repository/pull_request_repository', () => ({ + PullRequestRepository: jest.fn().mockImplementation(() => ({ + updateDescription: mockUpdateDescription, + })), +})); + +function baseParam(overrides: Record = {}) { + return { + owner: 'o', + repo: 'r', + issueNumber: 42, + tokens: { token: 't' }, + pullRequest: { number: 10, head: 'feature/42-x', base: 'develop', creator: 'alice' }, + ai: new Ai('http://localhost:4096', 'model', false, false, [], false, 'low', 20), + ...overrides, + } as unknown as Parameters[0]; +} + +describe('UpdatePullRequestDescriptionUseCase', () => { + let useCase: UpdatePullRequestDescriptionUseCase; + + beforeEach(() => { + useCase = new UpdatePullRequestDescriptionUseCase(); + mockGetIssueDescription.mockResolvedValue('Issue description'); + mockGetAllMembers.mockResolvedValue(['alice', 'bob']); + mockAskAgent.mockResolvedValue('## Summary\nPR does X.'); + mockUpdateDescription.mockResolvedValue(undefined); + }); + + it('returns failure when head or base branch is missing', async () => { + const param = baseParam({ pullRequest: { number: 10, head: '', base: 'develop', creator: 'alice' } }); + const results = await useCase.invoke(param); + expect(results[0].success).toBe(false); + expect(results[0].steps?.some((s) => s.includes('Could not determine PR branches'))).toBe(true); + }); + + it('returns failure when no issue description', async () => { + mockGetIssueDescription.mockResolvedValue(''); + const param = baseParam(); + const results = await useCase.invoke(param); + expect(results[0].success).toBe(false); + expect(results[0].steps?.some((s) => s.includes('No issue description'))).toBe(true); + }); + + it('updates PR description when AI returns body and creator is team member', async () => { + const param = baseParam(); + const results = await useCase.invoke(param); + expect(mockAskAgent).toHaveBeenCalled(); + expect(mockUpdateDescription).toHaveBeenCalledWith('o', 'r', 10, '## Summary\nPR does X.', 't'); + expect(results.some((r) => r.success === true)).toBe(true); + }); + + it('returns failure when AI returns empty description', async () => { + mockAskAgent.mockResolvedValue(''); + const param = baseParam(); + const results = await useCase.invoke(param); + expect(results[0].success).toBe(false); + expect(results[0].steps?.some((s) => s.includes('did not return a PR description'))).toBe(true); + }); + + it('returns failure on error', async () => { + mockGetIssueDescription.mockRejectedValue(new Error('API error')); + const param = baseParam(); + const results = await useCase.invoke(param); + expect(results[0].success).toBe(false); + }); +}); diff --git a/src/usecase/steps/pull_request/check_priority_pull_request_size_use_case.ts b/src/usecase/steps/pull_request/check_priority_pull_request_size_use_case.ts index 587bd201..45e1c3ab 100644 --- a/src/usecase/steps/pull_request/check_priority_pull_request_size_use_case.ts +++ b/src/usecase/steps/pull_request/check_priority_pull_request_size_use_case.ts @@ -2,6 +2,7 @@ import { Execution } from "../../../data/model/execution"; import { Result } from "../../../data/model/result"; import { ProjectRepository } from "../../../data/repository/project_repository"; import { logDebugInfo, logError, logInfo } from "../../../utils/logger"; +import { getTaskEmoji } from "../../../utils/task_emoji"; import { ParamUseCase } from "../../base/param_usecase"; export class CheckPriorityPullRequestSizeUseCase implements ParamUseCase { @@ -10,7 +11,7 @@ export class CheckPriorityPullRequestSizeUseCase implements ParamUseCase { - logInfo(`Executing ${this.taskId}.`) + logInfo(`${getTaskEmoji(this.taskId)} Executing ${this.taskId}.`) const result: Result[] = [] try { diff --git a/src/usecase/steps/pull_request/link_pull_request_issue_use_case.ts b/src/usecase/steps/pull_request/link_pull_request_issue_use_case.ts index 1c5b4c96..2272aaf1 100644 --- a/src/usecase/steps/pull_request/link_pull_request_issue_use_case.ts +++ b/src/usecase/steps/pull_request/link_pull_request_issue_use_case.ts @@ -3,6 +3,7 @@ import { Execution } from "../../../data/model/execution"; import { Result } from "../../../data/model/result"; import { PullRequestRepository } from "../../../data/repository/pull_request_repository"; import { logError, logInfo } from "../../../utils/logger"; +import { getTaskEmoji } from "../../../utils/task_emoji"; import { ParamUseCase } from "../../base/param_usecase"; export class LinkPullRequestIssueUseCase implements ParamUseCase { @@ -11,7 +12,7 @@ export class LinkPullRequestIssueUseCase implements ParamUseCase { - logInfo(`Executing ${this.taskId}.`) + logInfo(`${getTaskEmoji(this.taskId)} Executing ${this.taskId}.`) const result: Result[] = [] diff --git a/src/usecase/steps/pull_request/link_pull_request_project_use_case.ts b/src/usecase/steps/pull_request/link_pull_request_project_use_case.ts index 88b919f0..4914cd4a 100644 --- a/src/usecase/steps/pull_request/link_pull_request_project_use_case.ts +++ b/src/usecase/steps/pull_request/link_pull_request_project_use_case.ts @@ -2,6 +2,7 @@ import { Execution } from "../../../data/model/execution"; import { Result } from "../../../data/model/result"; import { ProjectRepository } from "../../../data/repository/project_repository"; import { logError, logInfo } from "../../../utils/logger"; +import { getTaskEmoji } from "../../../utils/task_emoji"; import { ParamUseCase } from "../../base/param_usecase"; export class LinkPullRequestProjectUseCase implements ParamUseCase { @@ -10,7 +11,7 @@ export class LinkPullRequestProjectUseCase implements ParamUseCase { - logInfo(`Executing ${this.taskId}.`) + logInfo(`${getTaskEmoji(this.taskId)} Executing ${this.taskId}.`) const result: Result[] = [] diff --git a/src/usecase/steps/pull_request/sync_size_and_progress_labels_from_issue_to_pr_use_case.ts b/src/usecase/steps/pull_request/sync_size_and_progress_labels_from_issue_to_pr_use_case.ts index a5e9943e..4d87797a 100644 --- a/src/usecase/steps/pull_request/sync_size_and_progress_labels_from_issue_to_pr_use_case.ts +++ b/src/usecase/steps/pull_request/sync_size_and_progress_labels_from_issue_to_pr_use_case.ts @@ -2,6 +2,7 @@ import { Execution } from "../../../data/model/execution"; import { Result } from "../../../data/model/result"; import { IssueRepository, PROGRESS_LABEL_PATTERN } from "../../../data/repository/issue_repository"; import { logDebugInfo, logError, logInfo } from "../../../utils/logger"; +import { getTaskEmoji } from "../../../utils/task_emoji"; import { ParamUseCase } from "../../base/param_usecase"; /** @@ -15,7 +16,7 @@ export class SyncSizeAndProgressLabelsFromIssueToPrUseCase implements ParamUseCa private issueRepository = new IssueRepository(); async invoke(param: Execution): Promise { - logInfo(`Executing ${this.taskId}.`); + logInfo(`${getTaskEmoji(this.taskId)} Executing ${this.taskId}.`); const result: Result[] = []; try { diff --git a/src/usecase/steps/pull_request/update_pull_request_description_use_case.ts b/src/usecase/steps/pull_request/update_pull_request_description_use_case.ts index d527bd77..9e8b6244 100644 --- a/src/usecase/steps/pull_request/update_pull_request_description_use_case.ts +++ b/src/usecase/steps/pull_request/update_pull_request_description_use_case.ts @@ -5,6 +5,7 @@ import { IssueRepository } from "../../../data/repository/issue_repository"; import { ProjectRepository } from "../../../data/repository/project_repository"; import { PullRequestRepository } from "../../../data/repository/pull_request_repository"; import { logDebugInfo, logError } from "../../../utils/logger"; +import { getTaskEmoji } from "../../../utils/task_emoji"; import { ParamUseCase } from "../../base/param_usecase"; export class UpdatePullRequestDescriptionUseCase implements ParamUseCase { @@ -16,7 +17,7 @@ export class UpdatePullRequestDescriptionUseCase implements ParamUseCase { - logDebugInfo(`Executing ${this.taskId}.`); + logDebugInfo(`${getTaskEmoji(this.taskId)} Executing ${this.taskId}.`); const result: Result[] = []; diff --git a/src/usecase/steps/pull_request_review_comment/check_pull_request_comment_language_use_case.ts b/src/usecase/steps/pull_request_review_comment/check_pull_request_comment_language_use_case.ts index bc7e4434..287936ad 100644 --- a/src/usecase/steps/pull_request_review_comment/check_pull_request_comment_language_use_case.ts +++ b/src/usecase/steps/pull_request_review_comment/check_pull_request_comment_language_use_case.ts @@ -8,6 +8,7 @@ import { } from "../../../data/repository/ai_repository"; import { IssueRepository } from "../../../data/repository/issue_repository"; import { logInfo } from "../../../utils/logger"; +import { getTaskEmoji } from "../../../utils/task_emoji"; import { ParamUseCase } from "../../base/param_usecase"; export class CheckPullRequestCommentLanguageUseCase implements ParamUseCase { @@ -20,7 +21,7 @@ If you'd like this comment to be translated again, please delete the entire comm -->`; async invoke(param: Execution): Promise { - logInfo(`Executing ${this.taskId}.`) + logInfo(`${getTaskEmoji(this.taskId)} Executing ${this.taskId}.`) const results: Result[] = [] diff --git a/src/utils/__tests__/setup_files.test.ts b/src/utils/__tests__/setup_files.test.ts new file mode 100644 index 00000000..2de11eac --- /dev/null +++ b/src/utils/__tests__/setup_files.test.ts @@ -0,0 +1,102 @@ +import * as fs from 'fs'; +import * as path from 'path'; +import * as os from 'os'; +import { ensureGitHubDirs, copySetupFiles } from '../setup_files'; + +jest.mock('../logger', () => ({ + logInfo: jest.fn(), +})); + +describe('setup_files', () => { + let tmpDir: string; + + beforeEach(() => { + tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'setup_files_test_')); + }); + + afterEach(() => { + if (fs.existsSync(tmpDir)) { + fs.rmSync(tmpDir, { recursive: true, force: true }); + } + }); + + describe('ensureGitHubDirs', () => { + it('creates .github, .github/workflows and .github/ISSUE_TEMPLATE when they do not exist', () => { + ensureGitHubDirs(tmpDir); + expect(fs.existsSync(path.join(tmpDir, '.github'))).toBe(true); + expect(fs.existsSync(path.join(tmpDir, '.github', 'workflows'))).toBe(true); + expect(fs.existsSync(path.join(tmpDir, '.github', 'ISSUE_TEMPLATE'))).toBe(true); + }); + + it('does not fail when directories already exist', () => { + fs.mkdirSync(path.join(tmpDir, '.github'), { recursive: true }); + fs.mkdirSync(path.join(tmpDir, '.github', 'workflows'), { recursive: true }); + fs.mkdirSync(path.join(tmpDir, '.github', 'ISSUE_TEMPLATE'), { recursive: true }); + expect(() => ensureGitHubDirs(tmpDir)).not.toThrow(); + expect(fs.existsSync(path.join(tmpDir, '.github', 'workflows'))).toBe(true); + }); + }); + + describe('copySetupFiles', () => { + it('returns { copied: 0, skipped: 0 } when setup/ does not exist', () => { + const result = copySetupFiles(tmpDir); + expect(result).toEqual({ copied: 0, skipped: 0 }); + }); + + it('copies workflow yml files from setup/workflows to .github/workflows', () => { + fs.mkdirSync(path.join(tmpDir, 'setup', 'workflows'), { recursive: true }); + fs.mkdirSync(path.join(tmpDir, '.github', 'workflows'), { recursive: true }); + const workflowContent = 'name: test'; + fs.writeFileSync(path.join(tmpDir, 'setup', 'workflows', 'ci.yml'), workflowContent); + const result = copySetupFiles(tmpDir); + expect(result.copied).toBe(1); + expect(fs.readFileSync(path.join(tmpDir, '.github', 'workflows', 'ci.yml'), 'utf8')).toBe(workflowContent); + }); + + it('skips workflow file when destination already exists', () => { + fs.mkdirSync(path.join(tmpDir, 'setup', 'workflows'), { recursive: true }); + fs.mkdirSync(path.join(tmpDir, '.github', 'workflows'), { recursive: true }); + fs.writeFileSync(path.join(tmpDir, 'setup', 'workflows', 'ci.yml'), 'from-setup'); + fs.writeFileSync(path.join(tmpDir, '.github', 'workflows', 'ci.yml'), 'existing'); + const result = copySetupFiles(tmpDir); + expect(result.skipped).toBe(1); + expect(result.copied).toBe(0); + expect(fs.readFileSync(path.join(tmpDir, '.github', 'workflows', 'ci.yml'), 'utf8')).toBe('existing'); + }); + + it('copies ISSUE_TEMPLATE files when setup/ISSUE_TEMPLATE exists', () => { + fs.mkdirSync(path.join(tmpDir, 'setup', 'ISSUE_TEMPLATE'), { recursive: true }); + fs.mkdirSync(path.join(tmpDir, '.github', 'ISSUE_TEMPLATE'), { recursive: true }); + fs.writeFileSync(path.join(tmpDir, 'setup', 'ISSUE_TEMPLATE', 'bug_report.yml'), 'title: Bug'); + const result = copySetupFiles(tmpDir); + expect(result.copied).toBe(1); + expect(fs.readFileSync(path.join(tmpDir, '.github', 'ISSUE_TEMPLATE', 'bug_report.yml'), 'utf8')).toBe('title: Bug'); + }); + + it('copies pull_request_template.md when it exists in setup/', () => { + fs.mkdirSync(path.join(tmpDir, 'setup'), { recursive: true }); + fs.mkdirSync(path.join(tmpDir, '.github'), { recursive: true }); + fs.writeFileSync(path.join(tmpDir, 'setup', 'pull_request_template.md'), '# PR template'); + const result = copySetupFiles(tmpDir); + expect(result.copied).toBe(1); + expect(fs.readFileSync(path.join(tmpDir, '.github', 'pull_request_template.md'), 'utf8')).toBe('# PR template'); + }); + + it('copies .env when it exists in setup/ and is a file', () => { + fs.mkdirSync(path.join(tmpDir, 'setup'), { recursive: true }); + fs.writeFileSync(path.join(tmpDir, 'setup', '.env'), 'SECRET=xxx'); + const result = copySetupFiles(tmpDir); + expect(result.copied).toBe(1); + expect(fs.readFileSync(path.join(tmpDir, '.env'), 'utf8')).toBe('SECRET=xxx'); + }); + + it('skips .env when destination .env already exists', () => { + fs.mkdirSync(path.join(tmpDir, 'setup'), { recursive: true }); + fs.writeFileSync(path.join(tmpDir, 'setup', '.env'), 'from-setup'); + fs.writeFileSync(path.join(tmpDir, '.env'), 'existing'); + const result = copySetupFiles(tmpDir); + expect(result.skipped).toBe(1); + expect(fs.readFileSync(path.join(tmpDir, '.env'), 'utf8')).toBe('existing'); + }); + }); +}); diff --git a/src/utils/constants.ts b/src/utils/constants.ts index c0ffe7dc..efc399e9 100644 --- a/src/utils/constants.ts +++ b/src/utils/constants.ts @@ -1,6 +1,5 @@ -export const COMMAND = 'giik' -export const TITLE = 'Giik' -export const REPO_URL = 'https://github.com/landamessenger/git-board-flow' +export const TITLE = 'Copilot' +export const REPO_URL = 'https://github.com/vypdev/copilot' /** Default OpenCode model: provider/modelID (e.g. opencode/kimi-k2.5-free). Reuse for CLI, action and Ai fallbacks. */ export const OPENCODE_DEFAULT_MODEL = 'opencode/kimi-k2.5-free' @@ -400,8 +399,8 @@ export const ACTIONS = { RECOMMEND_STEPS: 'recommend_steps_action', } as const; -/** Hidden HTML comment prefix for bugbot findings (issue/PR comments). Format: */ -export const BUGBOT_MARKER_PREFIX = 'gbf-bugbot'; +/** Hidden HTML comment prefix for bugbot findings (issue/PR comments). Format: */ +export const BUGBOT_MARKER_PREFIX = 'copilot-bugbot'; /** Max number of individual bugbot comments to create per issue/PR. Excess findings get one summary comment suggesting to review locally. */ export const BUGBOT_MAX_COMMENTS = 20; diff --git a/src/utils/opencode_server.ts b/src/utils/opencode_server.ts index ce9c4cd2..97c799d5 100644 --- a/src/utils/opencode_server.ts +++ b/src/utils/opencode_server.ts @@ -118,7 +118,7 @@ export async function startOpencodeServer(options?: { ['-y', 'opencode-ai', 'serve', '--port', String(port), '--hostname', hostname], { cwd, - env: { ...process.env, OPENCODE_CLIENT: 'git-board-flow' }, + env: { ...process.env, OPENCODE_CLIENT: 'copilot' }, stdio: ['ignore', 'pipe', 'pipe'], shell: false, } diff --git a/src/utils/setup_files.ts b/src/utils/setup_files.ts new file mode 100644 index 00000000..50407f5b --- /dev/null +++ b/src/utils/setup_files.ts @@ -0,0 +1,101 @@ +import * as fs from 'fs'; +import * as path from 'path'; +import { logInfo } from './logger'; + +/** + * Ensure .github, .github/workflows and .github/ISSUE_TEMPLATE exist; create them if missing. + * @param cwd - Directory (repo root) + */ +export function ensureGitHubDirs(cwd: string): void { + const githubDir = path.join(cwd, '.github'); + const workflowsDir = path.join(cwd, '.github', 'workflows'); + const issueTemplateDir = path.join(cwd, '.github', 'ISSUE_TEMPLATE'); + if (!fs.existsSync(githubDir)) { + logInfo('📁 Creating .github/...'); + fs.mkdirSync(githubDir, { recursive: true }); + } + if (!fs.existsSync(workflowsDir)) { + logInfo('📁 Creating .github/workflows/...'); + fs.mkdirSync(workflowsDir, { recursive: true }); + } + if (!fs.existsSync(issueTemplateDir)) { + logInfo('📁 Creating .github/ISSUE_TEMPLATE/...'); + fs.mkdirSync(issueTemplateDir, { recursive: true }); + } +} + +/** + * Copy setup files from setup/ to repo (.github/ workflows, ISSUE_TEMPLATE, pull_request_template.md, .env at root). + * Skips files that already exist at destination (no overwrite). + * Logs each file copied or skipped. No-op if setup/ does not exist. + * @param cwd - Repo root + * @returns { copied, skipped } + */ +export function copySetupFiles(cwd: string): { copied: number; skipped: number } { + const setupDir = path.join(cwd, 'setup'); + if (!fs.existsSync(setupDir)) return { copied: 0, skipped: 0 }; + + let copied = 0; + let skipped = 0; + const workflowsSrc = path.join(setupDir, 'workflows'); + const workflowsDst = path.join(cwd, '.github', 'workflows'); + if (fs.existsSync(workflowsSrc)) { + const files = fs.readdirSync(workflowsSrc).filter((f) => f.endsWith('.yml') || f.endsWith('.yaml')); + for (const f of files) { + const src = path.join(workflowsSrc, f); + const dst = path.join(workflowsDst, f); + if (fs.statSync(src).isFile()) { + if (fs.existsSync(dst)) { + logInfo(` ⏭️ .github/workflows/${f} already exists; skipping.`); + skipped += 1; + } else { + fs.copyFileSync(src, dst); + logInfo(` ✅ Copied setup/workflows/${f} → .github/workflows/${f}`); + copied += 1; + } + } + } + } + const issueTemplateSrc = path.join(setupDir, 'ISSUE_TEMPLATE'); + const issueTemplateDst = path.join(cwd, '.github', 'ISSUE_TEMPLATE'); + if (fs.existsSync(issueTemplateSrc)) { + const files = fs.readdirSync(issueTemplateSrc).filter((f) => fs.statSync(path.join(issueTemplateSrc, f)).isFile()); + for (const f of files) { + const src = path.join(issueTemplateSrc, f); + const dst = path.join(issueTemplateDst, f); + if (fs.existsSync(dst)) { + logInfo(` ⏭️ .github/ISSUE_TEMPLATE/${f} already exists; skipping.`); + skipped += 1; + } else { + fs.copyFileSync(src, dst); + logInfo(` ✅ Copied setup/ISSUE_TEMPLATE/${f} → .github/ISSUE_TEMPLATE/${f}`); + copied += 1; + } + } + } + const prTemplateSrc = path.join(setupDir, 'pull_request_template.md'); + const prTemplateDst = path.join(cwd, '.github', 'pull_request_template.md'); + if (fs.existsSync(prTemplateSrc)) { + if (fs.existsSync(prTemplateDst)) { + logInfo(' ⏭️ .github/pull_request_template.md already exists; skipping.'); + skipped += 1; + } else { + fs.copyFileSync(prTemplateSrc, prTemplateDst); + logInfo(' ✅ Copied setup/pull_request_template.md → .github/pull_request_template.md'); + copied += 1; + } + } + const envSrc = path.join(setupDir, '.env'); + const envDst = path.join(cwd, '.env'); + if (fs.existsSync(envSrc) && fs.statSync(envSrc).isFile()) { + if (fs.existsSync(envDst)) { + logInfo(' ⏭️ .env already exists; skipping.'); + skipped += 1; + } else { + fs.copyFileSync(envSrc, envDst); + logInfo(' ✅ Copied setup/.env → .env'); + copied += 1; + } + } + return { copied, skipped }; +} diff --git a/src/utils/task_emoji.ts b/src/utils/task_emoji.ts new file mode 100644 index 00000000..cc63dfb6 --- /dev/null +++ b/src/utils/task_emoji.ts @@ -0,0 +1,63 @@ +/** + * Representative emoji per task for "Executing {taskId}" logs. + * Makes it easier to visually identify the step type in the action output. + */ +const TASK_EMOJI: Record = { + // Main use cases + CommitUseCase: '📤', + IssueUseCase: '📋', + PullRequestUseCase: '🔀', + IssueCommentUseCase: '💬', + PullRequestReviewCommentUseCase: '💬', + SingleActionUseCase: '⚡', + // Issue steps + PrepareBranchesUseCase: '🌿', + CheckPermissionsUseCase: '🔐', + UpdateTitleUseCase: '✏️', + AssignMemberToIssueUseCase: '👤', + AssignReviewersToIssueUseCase: '👀', + LinkIssueProjectUseCase: '🔗', + LinkPullRequestProjectUseCase: '🔗', + LinkPullRequestIssueUseCase: '🔗', + CheckPriorityIssueSizeUseCase: '📏', + CheckPriorityPullRequestSizeUseCase: '📏', + CloseNotAllowedIssueUseCase: '🚫', + CloseIssueAfterMergingUseCase: '✅', + RemoveIssueBranchesUseCase: '🧹', + RemoveNotNeededBranchesUseCase: '🧹', + DeployAddedUseCase: '🏷️', + DeployedAddedUseCase: '🏷️', + MoveIssueToInProgressUseCase: '📥', + UpdateIssueTypeUseCase: '🏷️', + // Commit steps + NotifyNewCommitOnIssueUseCase: '📢', + CheckChangesIssueSizeUseCase: '📐', + DetectPotentialProblemsUseCase: '🔍', + // PR steps + SyncSizeAndProgressLabelsFromIssueToPrUseCase: '🔄', + UpdatePullRequestDescriptionUseCase: '✏️', + CheckIssueCommentLanguageUseCase: '🌐', + CheckPullRequestCommentLanguageUseCase: '🌐', + // Common steps + PublishResultUseCase: '📄', + StoreConfigurationUseCase: '⚙️', + GetReleaseVersionUseCase: '🏷️', + GetReleaseTypeUseCase: '🏷️', + GetHotfixVersionUseCase: '🏷️', + CommitPrefixBuilderUseCase: '📜', + ThinkUseCase: '💭', + // Actions + CheckProgressUseCase: '📊', + RecommendStepsUseCase: '💡', + CreateReleaseUseCase: '🎉', + CreateTagUseCase: '🏷️', + PublishGithubActionUseCase: '📦', + DeployedActionUseCase: '🚀', + InitialSetupUseCase: '🛠️', +}; + +const DEFAULT_EMOJI = '▶️'; + +export function getTaskEmoji(taskId: string): string { + return TASK_EMOJI[taskId] ?? DEFAULT_EMOJI; +}