Skip to content

feat(issue): core duplicate-picker mod and packaging parity (part 1 of #2075) - #2076

Merged
shahar1 merged 1 commit into
apache:mainfrom
Kaap10:feat/issue-duplicate-picker-mod
Nov 14, 2026
Merged

shahar1 merged 1 commit into
apache:mainfrom
Kaap10:feat/issue-duplicate-picker-mod

Conversation

@Kaap10

@Kaap10 Kaap10 commented Nov 14, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • Implements part 1 of feat(issue): interactive duplicate-picker pane mod for issue-deduplicate #2075: introduces the core Claude Code mod for plugins/magpie-issue to provide an interactive duplicate-picker side pane (Pane), moving candidate issue comparisons out of the chat transcript.
  • In plugins/magpie-issue/hooks/:
    • types.ts & types.d.ts: defined TypeScript interfaces (CandidateIssue, DuplicateCandidatePayload, DuplicatePickerDecision, DuplicatePickerState) and ambient PluginState declaration for magpie-issue.duplicatePickerState.
    • duplicate-picker.ts:
      • Reactive state storage via atom({ plugin: 'magpie-issue', key: 'duplicatePickerState' }, null).
      • Input sanitization (sanitizeText): preserves valid generic type syntax (e.g. Map<String, Foo>) while stripping ANSI sequences, control codes, zero-width characters, and Unicode bidirectional overrides from untrusted external titles and excerpts.
      • Decision serializer (serializeDecision): status-aware serialization that keeps untouched reviewing states from prematurely dropping candidates, and provides explicit canonical curation.
      • Interactive UI pane renderer (renderDuplicatePickerPane) targeting ui.render (Pane) using single-props element constructors (Text({ children: [...] }), Box({ ... }), Button({ key, label, onPress }), strikethrough: boolean, color: 'dim').
      • Explicit canonical selection button (Keep Target #${targetIssue} (Canonical)) allowing maintainer sign-off on keeping the target issue and dropping duplicate candidates.
      • Middleware-compliant hook registration (register) properly chaining next(e) for both session.start and ui.render with { component: 'Pane' } matcher.
    • hooks.json: declared mod module with $schema.
    • duplicate-picker.test.ts: comprehensive test suite covering sanitization, schema validation, candidate deduplication, button onPress state transitions, similarity score ranges, and UI tree composition (24 tests, 100% pass).
  • In docs/setup/secure-agent-setup.md:
    • Documented threat model, boundaries, and human sign-off contract for the duplicate candidate picker mod.
  • Cross-harness packaging parity:
    • Updated tools/dev/check-family-plugins.py to register magpie-issue in CODEX_FAMILY_HOOKS.
    • Added plugins/magpie-issue/.codex-plugin/plugin.json pointing to an empty hooks/codex-hooks.json so Codex does not encounter Claude Code $schema keys.
    • Added "types": "./hooks/types.d.ts" to plugins/magpie-issue/.claude-plugin/plugin.json.

Type of change

  • Skill change (.claude/skills/<name>/) — eval fixtures updated below
  • Tool / bridge contract (tools/<system>/*.md)
  • Python package (tools/*/ with pyproject.toml)
  • Groovy reference impl
  • Cross-cutting (RFC, AGENTS.md, sandbox, privacy-LLM)
  • Documentation (docs/, README.md, CONTRIBUTING.md)
  • Project template (projects/_template/)
  • CI / dev loop (prek, workflows, validators)
  • Other:

Test plan

  • claude plugin validate --strict plugins/magpie-issue passes with 0 errors
  • claude plugin test plugins/magpie-issue passes (24 passed, 0 failed)
  • ruff check tools/dev/check-family-plugins.py passes
  • ruff format --check tools/dev/check-family-plugins.py passes
  • mypy tools/dev/check-family-plugins.py passes (0 type issues)
  • Pre-commit hooks (doctoc, trailing-whitespace, end-of-file-fixer, detect-private-key, check-merge-conflict) pass on all staged files

RFC-AI-0004 compliance

  • HITL — any new mutation is gated on explicit user confirmation (pane defaults to reviewing, zero candidate drops without maintainer button press)
  • Sandbox — no new unrestricted host access; network reach declared in the adapter
  • Vendor neutrality — placeholders (<PROJECT>, <tracker>, <upstream>, <security-list>) used in all skill / tool prose
  • Conversational + correctable — agentic-override path documented if behaviour is adopter-tunable
  • Write-access discipline — no autonomous outbound messages; drafts only, sent on confirmation
  • Privacy LLM — private content does not reach a non-approved LLM; redactor invoked where needed

Linked issues

Refs #2075 (part 1 of 2: core duplicate-picker mod, packaging parity, and test suite)

Notes for reviewers (optional)

  • Strictly Additive: This PR adds the underlying mod, documentation, and packaging definitions. Part 2 will wire the session file contract into the issue-deduplicate and issue-triage skills, ensuring full vendor-neutral fallback for non-Claude harnesses.
  • Fail-Open: All UI and state interactions are wrapped in fail-open handlers to ensure headless or non-interactive environments run without error.

@github-actions github-actions Bot added family:tools tools/* family:ci .github workflows, prek, validators family:issue issue-* skills substrate:framework-dev Tool substrate: build / validate / eval the framework itself labels Nov 14, 2026
@Kaap10
Kaap10 marked this pull request as draft November 14, 2026 05:52
@Kaap10
Kaap10 force-pushed the feat/issue-duplicate-picker-mod branch 3 times, most recently from 60dc9c0 to a1d867d Compare November 14, 2026 06:13
@Kaap10
Kaap10 marked this pull request as ready for review November 14, 2026 06:19
@Kaap10
Kaap10 requested a review from potiuk November 14, 2026 06:25

@shahar1 shahar1 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The packaging half is in order, but the pane renderer calls the UI elements with a signature the mod API does not have, so it would draw nothing, and the tests mock that same wrong signature.

Hook logic must be tested using claude plugin test (plugins/magpie-issue/hooks/duplicate-picker.ts:249)

Every mod must include unit tests and pass strict validation before landing:
2. Automated Unit Tests: Hook logic must be tested using claude plugin test with corresponding *.test.ts test suites written against claude-code/testing.

Text({ bold: true, color: 'info' }, `[Deduplication Target: #${state.targetIssue}]`),
...
Button({ label: ..., onClick: async () => { ... } })

The elements $.ui.resolve(e) returns take one props argument, with children among the props (ElementConstructor<P> = (props: P & ElementChildren) => RenderElement in the Claude Code 2.1.325 mod types), and a Button press handler is onPress, not onClick. As written, every Text(props, content) and Box(props, ...children) call drops its second argument, so the pane draws no text and no buttons, and strikeThrough is not a Text prop (strikethrough is). The suite passes because its mock Box / Text accept positional children. Please follow the shape plugins/magpie-pr-management/hooks/review-findings.ts uses (Text({ children: [...] }), Button({ key, label, onPress })), make the test mocks single-argument so they fail on the current code, and check the pane once in a real session.

Smaller observations

  • general — The PR body describes things the diff does not contain: a "two-way session artifact reader" (nothing in the module reads a file, and nothing ever sets the state to a non-null value, so the pane cannot appear until part 2), and the Skill change, eval fixtures updated and Tool / bridge contract boxes are ticked with no skill, eval or tools/<system>/*.md change. Please bring the body in line with the diff.
  • See inline comments on plugins/magpie-issue/hooks/duplicate-picker.ts:177, plugins/magpie-issue/hooks/duplicate-picker.ts:76, plugins/magpie-issue/hooks/hooks.json:4, plugins/magpie-issue/hooks/duplicate-picker.ts:363, plugins/magpie-issue/hooks/duplicate-picker.ts:103, plugins/magpie-issue/hooks/duplicate-picker.test.ts:28.

This review was drafted by an AI-assisted tool and
confirmed by an Apache Magpie maintainer. The findings
below are observations, not blockers; an Apache Magpie
maintainer — a real person — will take the next look at the
PR. If you think a finding is mis-applied, please reply on
the PR and a maintainer will weigh in.

More on how Apache Magpie handles maintainer review:
Contributing guide.

Comment thread plugins/magpie-issue/hooks/hooks.json Resolved
@Kaap10
Kaap10 force-pushed the feat/issue-duplicate-picker-mod branch from a1d867d to c2673d6 Compare November 14, 2026 09:14
@github-actions github-actions Bot added family:setup setup-* skills family:docs Docs, MISSION.md, READMEs labels Nov 14, 2026
@Kaap10
Kaap10 requested a review from shahar1 November 14, 2026 09:35

@shahar1 shahar1 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The earlier round is addressed and the element shapes now match the sibling mod; what remains is state bookkeeping in the press handlers, an untested render handler, and docs that describe a pane this part does not yet feed — none blocking.

Smaller observations

  • tools/spec-loop/specs/issue-management-family.md — tools/spec-loop/specs/pr-management-family.md records its plugin's mod, its hooks/ files and the Codex hook file. issue-management-family.md says nothing about this one. Add the entry here, or name the part of #2075 that carries it.
  • See inline comments on plugins/magpie-issue/hooks/duplicate-picker.ts:395, plugins/magpie-issue/hooks/duplicate-picker.ts:52, plugins/magpie-issue/hooks/duplicate-picker.ts:372, docs/setup/secure-agent-setup.md:2049, docs/setup/secure-agent-setup.md:2051, plugins/magpie-issue/hooks/duplicate-picker.test.ts:571, plugins/magpie-issue/hooks/types.ts:27.

This review was drafted by an AI-assisted tool and
confirmed by an Apache Magpie maintainer. The findings
below are observations, not blockers; an Apache Magpie
maintainer — a real person — will take the next look at the
PR. If you think a finding is mis-applied, please reply on
the PR and a maintainer will weigh in.

More on how Apache Magpie handles maintainer review:
Contributing guide.

Comment thread docs/setup/secure-agent-setup.md Resolved
Comment thread docs/setup/secure-agent-setup.md Resolved
Comment thread plugins/magpie-issue/hooks/types.ts Resolved
@Kaap10
Kaap10 force-pushed the feat/issue-duplicate-picker-mod branch from c2673d6 to 7bac93a Compare November 14, 2026 10:36
@github-actions github-actions Bot added the family:dev Repo dev: .asf.yaml, spec-loop specs, Node manifests, .claude/settings.json label Nov 14, 2026

@shahar1 shahar1 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both earlier rounds are addressed in the code: status is derived from the selection, the press handlers update from the stored state, and both registered handlers are exercised; what is left are three notes that can ride with part 2.

Smaller observations

  • See inline comments on plugins/magpie-issue/hooks/duplicate-picker.ts:563, tools/spec-loop/specs/issue-management-family.md:192, plugins/magpie-issue/hooks/duplicate-picker.ts:135.

This review was drafted by an AI-assisted tool and
confirmed by an Apache Magpie maintainer. The maintainer
approving this PR has read the findings and signed off. If
something feels off, please reply on the PR and a maintainer
will follow up.

More on how Apache Magpie handles maintainer review:
Contributing guide.

@shahar1
shahar1 merged commit cab870a into apache:main Nov 14, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

family:ci .github workflows, prek, validators family:dev Repo dev: .asf.yaml, spec-loop specs, Node manifests, .claude/settings.json family:docs Docs, MISSION.md, READMEs family:issue issue-* skills family:setup setup-* skills family:tools tools/* substrate:framework-dev Tool substrate: build / validate / eval the framework itself

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants