From 7d7dfdf5c1136e5191f155ede42c40e44dad0c0d Mon Sep 17 00:00:00 2001 From: openhands Date: Mon, 24 Aug 2026 01:51:47 +0000 Subject: [PATCH] feat: add ready-for-dev issue and PR readiness gates Add an issue-readiness workflow that manages the ready-for-dev label with type-specific criteria tailored to the TypeScript client: bug reports need a reproducible JavaScript/TypeScript command (npm, pnpm, yarn, or npx) in the Actual Behavior section, and both bugs and enhancements need Acceptance Criteria checklist items (enhancements also need Desired Behavior). - check-issue-readiness.mjs always exits 0 in --json mode so not-ready results drive label/comment behavior without failing the workflow under set -euo pipefail - post-readiness-comment.mjs upserts a single feedback comment via a hidden marker (idempotent) - pr-description-check.yml gates PRs on linked issues carrying ready-for-dev (issues predating the rollout are grandfathered) - refresh-linked-pr-checks.mjs re-runs the PR gate for open PRs linked to an issue whose ready-for-dev label changed - Issue forms for bug reports and feature requests produce the sections the readiness check evaluates - Jest tests exercise the real CLI code paths via child processes, with a local HTTP server standing in for the GitHub API Fixes #357 Co-authored-by: openhands --- .github/ISSUE_TEMPLATE/bug_report.yml | 150 ++++++++++ .github/ISSUE_TEMPLATE/feature_request.yml | 77 +++++ .github/scripts/check-issue-readiness.mjs | 232 +++++++++++++++ .github/scripts/check-pr-description.mjs | 203 +++++++++++++ .github/scripts/post-readiness-comment.mjs | 193 ++++++++++++ .github/scripts/refresh-linked-pr-checks.mjs | 185 ++++++++++++ .github/workflows/issue-readiness-check.yml | 140 +++++++++ .github/workflows/pr-description-check.yml | 41 +++ src/__tests__/issue-readiness.test.ts | 243 ++++++++++++++++ src/__tests__/pr-description-check.test.ts | 290 +++++++++++++++++++ 10 files changed, 1754 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.yml create mode 100644 .github/ISSUE_TEMPLATE/feature_request.yml create mode 100644 .github/scripts/check-issue-readiness.mjs create mode 100644 .github/scripts/check-pr-description.mjs create mode 100644 .github/scripts/post-readiness-comment.mjs create mode 100644 .github/scripts/refresh-linked-pr-checks.mjs create mode 100644 .github/workflows/issue-readiness-check.yml create mode 100644 .github/workflows/pr-description-check.yml create mode 100644 src/__tests__/issue-readiness.test.ts create mode 100644 src/__tests__/pr-description-check.test.ts diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 0000000..d2c8ecf --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,150 @@ +--- +name: Bug +description: Report a problem with the OpenHands Agent Server TypeScript client +title: '[Bug]: ' +labels: [bug] +body: + - type: markdown + attributes: + value: | + ## Thank you for reporting a bug! 🐛 + + **Please fill out all required fields.** Issues are evaluated for + the `ready-for-dev` label automatically: a bug report is ready + when the Actual Behavior section includes a reproducible + JavaScript/TypeScript command and the Acceptance Criteria section + has at least one checklist item. + + - type: checkboxes + attributes: + label: Is there an existing issue for the same bug? + description: Please search existing issues before creating a new one. If found, react or comment on the duplicate issue instead. + options: + - label: I have searched existing issues and this is not a duplicate. + required: true + + - type: textarea + id: bug-description + attributes: + label: Bug Description + description: Clearly describe what went wrong. Be specific and concise. + placeholder: Example - RemoteConversation.start() rejects with a 404 when the conversation ID contains uppercase characters. + validations: + required: true + + - type: textarea + id: expected-behavior + attributes: + label: Expected Behavior + description: What did you expect to happen? + placeholder: Example - The conversation should start regardless of ID casing. + validations: + required: false + + - type: textarea + id: actual-behavior + attributes: + label: Actual Behavior + description: | + What actually happened? Include the reproducible command(s) you + ran (e.g. `npm test`, `npx tsx repro.ts`, `pnpm vitest run`) and + the observed output. + placeholder: | + Example - Running `npx tsx repro.ts` against @openhands/typescript-client 1.38.1 fails with: + ``` + Error: request failed with status 404 + ``` + validations: + required: true + + - type: textarea + id: reproduction-steps + attributes: + label: Steps to Reproduce + description: Provide clear, step-by-step instructions to reproduce the bug. + placeholder: | + 1. Install the client with `npm install @openhands/typescript-client` + 2. Create a RemoteConversation with an uppercase ID + 3. Call `await conversation.start()` + 4. Error appears + validations: + required: false + + - type: textarea + id: acceptance-criteria + attributes: + label: Acceptance Criteria + description: List the testable checklist item(s) that would prove this bug is fixed. + placeholder: | + - [ ] The reported error no longer occurs + - [ ] A regression test covers the reported scenario + validations: + required: true + + - type: input + id: client-version + attributes: + label: Client Version + description: What version of @openhands/typescript-client are you using? + placeholder: ex. 1.38.1, main branch, commit hash + validations: + required: false + + - type: input + id: runtime-version + attributes: + label: Runtime and Package Manager + description: Which runtime and package manager are you using? + placeholder: ex. Node 22.12 + npm 10, Node 24 + pnpm 9, browser (Vite) + validations: + required: false + + - type: input + id: agent-server-version + attributes: + label: Agent Server Version (if applicable) + description: Which agent-server image/version is the client talking to? + placeholder: ex. ghcr.io/openhands/agent-server:1.43.1-python + validations: + required: false + + - type: dropdown + id: os + attributes: + label: Operating System + options: + - MacOS + - Linux + - WSL on Windows + - Windows + - Other + validations: + required: false + + - type: textarea + id: logs + attributes: + label: Logs and Error Messages + description: Paste relevant logs, error messages, or stack traces. Use code blocks (```) for formatting. + placeholder: | + ``` + Paste error logs here + ``` + + - type: textarea + id: code-sample + attributes: + label: Minimal Code Sample + description: If possible, provide a minimal code sample that reproduces the issue. + placeholder: | + ```ts + import { RemoteConversation } from '@openhands/typescript-client'; + + // Your minimal reproducible code here + ``` + + - type: textarea + id: additional-context + attributes: + label: Screenshots and Additional Context + description: Add screenshots, environment details, dependency versions, or other context that helps explain the issue. diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 0000000..9e06bd8 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,77 @@ +--- +name: Feature Request or Enhancement +description: Suggest a new feature or improvement for the OpenHands Agent Server TypeScript client +title: '[Feature]: ' +labels: [enhancement] +body: + - type: markdown + attributes: + value: | + ## Thank you for suggesting a feature! 💡 + + Issues are evaluated for the `ready-for-dev` label automatically: + an enhancement is ready when it has a Desired Behavior section and + an Acceptance Criteria section with at least one checklist item. + + - type: checkboxes + attributes: + label: Is there an existing feature request for this? + description: Please search existing issues and feature requests before creating a new one. If found, react or comment on the duplicate issue instead. + options: + - label: I have searched existing issues and feature requests, and this is not a duplicate. + required: true + + - type: textarea + id: problem-statement + attributes: + label: Problem or Use Case + description: What problem are you trying to solve? What use case would this feature enable? + placeholder: Example - As a developer building a web UI on the agent-server API, I need typed access to conversation cost metrics so I can display usage to end users. + validations: + required: true + + - type: textarea + id: desired-behavior + attributes: + label: Desired Behavior + description: Describe your ideal solution. What should this feature do? How should it work? + placeholder: Example - Expose a `conversation.getCostMetrics()` method returning a typed `CostMetrics` object mirroring the agent-server response. + validations: + required: true + + - type: textarea + id: acceptance-criteria + attributes: + label: Acceptance Criteria + description: List the testable checklist item(s) that would prove this feature is complete. + placeholder: | + - [ ] The new method returns typed cost metrics from the agent-server + - [ ] Unit tests cover the new behavior + validations: + required: true + + - type: textarea + id: alternatives + attributes: + label: Alternatives Considered + description: Have you considered any alternative solutions or workarounds? What are their limitations? + placeholder: Example - Calling the REST endpoint directly with fetch, but that loses the client's type safety and error handling. + + - type: textarea + id: technical-details + attributes: + label: Technical Implementation Ideas (Optional) + description: If you have technical expertise, share implementation ideas, API suggestions, or relevant technical details. + placeholder: | + Example - Mirror the Python SDK's RemoteConversation cost API; the endpoint already exists in the OpenAPI spec at src/generated/agent-server-schema.ts. + + - type: textarea + id: additional-context + attributes: + label: Additional Context + description: Add any other context, code examples, API mockups, or references that help illustrate this feature request. + placeholder: | + ```ts + const metrics = await conversation.getCostMetrics(); + console.log(metrics.totalCostUsd); + ``` diff --git a/.github/scripts/check-issue-readiness.mjs b/.github/scripts/check-issue-readiness.mjs new file mode 100644 index 0000000..5d2b351 --- /dev/null +++ b/.github/scripts/check-issue-readiness.mjs @@ -0,0 +1,232 @@ +#!/usr/bin/env node + +/** + * Determine whether an issue meets the `ready-for-dev` readiness criteria. + * + * The criteria are type-specific: + * + * - Bug reports (labeled `bug`): the Actual Behavior section must describe a + * reproducible run of the TypeScript client and include a supported command + * (`npm`, `pnpm`, `yarn`, or `npx`), plus a non-empty Acceptance Criteria + * section with at least one checklist item. + * + * - Enhancements (labeled `enhancement`): the body must contain non-empty + * Desired Behavior and Acceptance Criteria sections, the latter with at + * least one checklist item. + * + * GitHub issue forms render each field as an `###