Resolve #74 merge conflict: sync .agent issue-fns.sh mirror with master (jira/ado) - #87
Conversation
Adds a first-class `jira` issue source alongside `file` and `github`, implementing the same uniform 9-verb backend contract (list, get, update, comment, close, create, claim, release, any-claimable) against the Jira REST API v2. - issues-jira.sh: self-contained backend. Maps Jira issues (PROJ-N) to the gh-compatible JSON shape, exposing the numeric key suffix as `number` so it stays compatible with the swarm manifest and the rest of the workflow. Uses API v2 for plain-text descriptions. Non-secret connection settings (baseUrl, project) come from the `jira` object in .autocoder.json; credentials are env-only (JIRA_EMAIL + JIRA_API_TOKEN, or JIRA_AUTH_HEADER for Server/DC PATs) and never committed. - Claimable/open JQL ORs in `labels is EMPTY` so label-less issues are not silently dropped — the Jira analogue of the GitHub `no:label` bug (#57). - Registers `jira` in both dispatchers (plugins + .agent mirror), issue-source-lib.sh validation, and the set-issue-source command. - test_issues_jira.sh: 35 assertions covering JQL, request shaping, output schema, and exit codes, with curl fully stubbed (no network). - Updates CLAUDE.md/GEMINI.md, launcher help strings, and bumps autocoder 4.5.2 -> 4.6.0 and the marketplace 3.26.0 -> 3.27.0. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015zJKDkbj54vZeGaTWLJEHv
The unit test (test_issues_jira.sh) stubs curl and asserts request/JQL shape; this adds real end-to-end coverage without any network: - tests/fixtures/fake_jira.py: a small stdlib-only STATEFUL fake of the Jira REST API v2 covering exactly the endpoints issues-jira.sh calls (search, issue CRUD, comment, transitions, assignee, myself). It keeps issues in memory and evaluates the JQL the backend emits, so state filters and the lifecycle behave like real Jira. Binds an ephemeral loopback port (printed as "LISTENING <port>") so CI runs never collide. - tests/test_issues_jira_integration.sh: starts the fake, exercises the full lifecycle (create → get → claim/release → comment → update → close) over real HTTP and asserts every state filter — including the label-less "labels is EMPTY" guard a stateless mock cannot exercise — then tears the server down. Skips cleanly if curl/python3 are absent. 17 assertions. - plugins/autocoder/scripts/jira-smoke-test.sh: opt-in check against a REAL Jira instance (JIRA_* env). Kept out of tests/ so CI never needs egress. - CLAUDE.md: document the three test layers. Full shell suite green (15/15); server teardown leaves no stray process. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015zJKDkbj54vZeGaTWLJEHv
Walks through creating a free Jira Cloud site, project, and API token; wiring the non-secret baseUrl/project into .autocoder.json while keeping credentials in the environment; verifying with jira-smoke-test.sh; and the two hermetic CI tests. No secrets in the doc. Linked from CLAUDE.md. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015zJKDkbj54vZeGaTWLJEHv
Adds a first-class `ado` issue source implementing the same uniform 9-verb backend contract against the Azure DevOps Work Item Tracking REST API. - issues-ado.sh: self-contained backend. Work item IDs are integers, so `number` maps to System.Id directly. Labels ↔ work-item Tags (System.Tags), state ↔ System.State (done-state set covers the default Agile/Basic/Scrum/CMMI processes). Uses WIQL for list/any-claimable, workitemsbatch for details, and json-patch for create/update. Non-secret orgUrl/project come from the `ado` object in .autocoder.json; the PAT is env-only (ADO_PAT) and never committed. Overridable work-item type and open/closed state names via env. - WIQL `[System.Tags] NOT CONTAINS 'x'` already matches tag-less items, so untagged work stays claimable without a special empty clause (the ADO analogue of the GitHub no:label / Jira empty-labels traps) — asserted by both tests. - Registers `ado` in both dispatchers (plugins + .agent mirror), issue-source-lib validation, the set-issue-source command, and launcher help strings. - Tests (both hermetic, in CI): test_issues_ado.sh (28 assertions, stubs curl; WIQL + json-patch shape, schema, exit codes) and test_issues_ado_integration.sh (18 assertions; real HTTP against a stateful fake, tests/fixtures/fake_ado.py, full lifecycle + WIQL filtering). - Docs: docs/ado-setup.md; updates CLAUDE.md/GEMINI.md. Bumps autocoder 4.6.0 -> 4.7.0 and the marketplace 3.27.0 -> 3.28.0. Full shell suite green (17/17). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015zJKDkbj54vZeGaTWLJEHv
- docs/issue-backends.md: unified overview of the four built-in backends — the 9-verb contract, uniform JSON shape and exit codes, per-backend model mapping, secrets handling, configuration precedence, and the hermetic test layers. Links to the Jira and ADO setup guides. - README: refresh the "Issue Backends" section — full 9-verb contract table (adds claim/release/any-claimable), point at the new docs, and use a genuinely custom name (linear) for the custom-backend example now that jira/ado are first-class. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015zJKDkbj54vZeGaTWLJEHv
Resolves .agent/scripts/issue-fns.sh to the canonical plugins version: the thin 9-verb dispatcher WITH the jira/ado cases. Recorded as a real two-parent merge so master's change is in the ancestry and the later merge to master is clean.
Two gaps found by a dry-run of the full merge chain. 1. issue-source-lib.sh existed only under plugins/autocoder/scripts/. It is issue-source resolution used by the swarm launch/lifecycle scripts — shared issue-layer infrastructure, not platform-specific — so the mirror was incomplete. Copied verbatim. 2. The parity guard's SHARED list covered only the two original backends (file, gh). issues-jira.sh and issues-ado.sh arrived with #83 and were never checked, and neither was issue-source-lib.sh. A backend that ships only under plugins/ is invisible to the guard — which is exactly how the drift in #71 went unnoticed: the mirror looked healthy because nothing checked the files missing from it. SHARED now lists the whole issue layer (7 files). Verification: parity guard 19/19, up from 13/13. Negative-tested both new assertion classes — removing issue-source-lib.sh from the mirror fails 2 assertions, and perturbing issues-jira.sh fails the divergence check — so the added coverage is not vacuous. 18/18 suites pass, build clean. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2b134b1 to
b214e16
Compare
|
Both dry-run findings folded in. Branch updated: 1. #87 did not fully clear #74 — fixedConfirmed, and the cause was mine. The file content was already correct; only the ancestry was wrong. Rebuilt the branch through the Git Data API so the merge is recorded with both parents ( 2. Mirror was short
|
Unblocks #74 (issue #71), which is currently CONFLICTING and cannot merge.
Base is
feature/issue-71, not master — merging this into that branch clears the conflict without force-pushing over #74's history.The conflict was semantic, not mechanical
One file conflicted:
.agent/scripts/issue-fns.sh..agent/workflows/fix.mdcalledissue_claim/issue_release/issue_any_claimable, which the old mirror never defined, so Antigravity's/fixexited 127 at preflight on every run._ifns_jira,_ifns_ado) from Add Jira and Azure DevOps issue backends (#81, #82) #83.Resolving "ours" would have silently deleted Jira and Azure DevOps support from the
.agentmirror. Worth flagging, because both sides look correct in isolation and the loss would not show up as a test failure on #74 alone.Resolution
Took the canonical
plugins/autocoder/scripts/issue-fns.shfrom master verbatim — it is already the thin dispatcher and carries thejira/adocases..agent/scripts/shipsissues-jira.shandissues-ado.sh, so those cases resolve.This is not a judgment call:
tests/test_agent_mirror_parity.sh(added by #74 itself) requires the shared files to be byte-identical across mirrors, which makes the canonical file the only valid resolution — and self-verifying.Verification
Suites verified directly rather than through
regression-test.sh: this branch predates #73, so the runner here can still report a false green and is not trustworthy as the gate.Merge order
feature/issue-71master(now conflict-free)🤖 Generated with Claude Code