feat: add agent_doc_sync JSRunner job#6
Conversation
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
JSRunner passes params to action() as {jobParams, ticket, response}.
Custom config must be nested under jobParams, not at the top level.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
New MCP tool signature: (owner, repo, workflowFile, inputsJson, ref) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- sm.json: new rule for 'In Review - Passed/Failed' Test Cases → pr_test_automation_review - smAgent.js: pass skipIfLabel as removeLabel in encoded_config - postTestReviewComments.js: remove params.removeLabel at end (SM idempotency cleanup) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add removeLabel to pr_test_automation_review.json params directly so postTestReviewComments.js receives it as params.removeLabel - Simplify buildEncodedConfig in smAgent.js (remove unused removeLabel passing via encoded_config which was not reaching postJSAction) Co-Authored-By: Claude Sonnet 4 <noreply@anthropic.com>
- Move removeLabel into customParams in pr_test_automation_review.json - Access it via params.jobParams.customParams.removeLabel in postTestReviewComments.js (correct Teammate params structure) Co-Authored-By: Claude Sonnet 4 <noreply@anthropic.com>
- preJSAction: moveToReadyForTesting.js (transition before test generation) - postJSAction: moveToInTesting.js (transition after test cases generated) - Add IN_TESTING status to config.js Co-Authored-By: Claude Sonnet 4 <noreply@anthropic.com>
- sm.json: new rule for 'In Rework' Test Cases → pr_test_automation_rework - pr_test_automation_rework.json: customParams.removeLabel for idempotency - postTestReworkResults.js: remove SM label via params.jobParams.customParams Co-Authored-By: Claude Sonnet 4 <noreply@anthropic.com>
…n_description→Ready For Development - jiraHelpers.assignForReview: add optional targetStatus param (default IN_REVIEW) - assignForReview.js: pass STATUSES.SOLUTION_ARCHITECTURE - enhanceSolutionDesignDescriptionAndAssess.js: pass STATUSES.READY_FOR_DEVELOPMENT Co-Authored-By: Claude Sonnet 4 <noreply@anthropic.com>
- sm.json: new rule for 'In Review' Stories → pr_review.json - pr_review.json: customParams.removeLabel for idempotency - postPRReviewComments.js: remove SM label via params.jobParams.customParams Co-Authored-By: Claude Sonnet 4 <noreply@anthropic.com>
- postTestReviewComments: track mergeSucceeded; if approved but merge failed → post conflict comment + move to In Rework - postPRReviewComments: if approved but merged=false → move to In Rework; add conflict panel to Jira comment Co-Authored-By: Claude Sonnet 4 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4 <noreply@anthropic.com>
…ys/skippedKeys format
GraalJS [].concat(undefined) produces [null], so all early-return paths must
return { processedKeys: [], skippedKeys: [] } instead of the old { processed: 0, skipped: 0 }.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…arams.customParams In Teammate postJSAction, the JSON config's params block is mapped directly onto the JS params object (verified by params.metadata being accessible directly). So customParams is at params.customParams, not params.jobParams.customParams. This fixes SM label removal (sm_test_review_triggered, sm_story_review_triggered, sm_test_rework_triggered) not working after review/rework agents completed. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…runs
JSRunner agent that queries failed GitHub workflow runs and creates a Bug ticket
per unique failure. Uses ci-run-{runId} label for idempotency (skips if label exists).
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…rkflows)
When workflowId is omitted, passes null to github_list_workflow_runs which should
use the /actions/runs endpoint instead of /actions/workflows/{id}/runs.
NOTE: if dmtools returns 404 without workflowId, report at https://github.com/IstiN/dmtools/issues
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…_ticket Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…stAutomationResults jira_create_ticket does not exist in dmtools MCP tools. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…customParams) params.metadata is a special shortcut field in dmtools, but customParams is not — it's only accessible via params.jobParams.customParams. This caused SM idempotency labels (sm_test_review_triggered, sm_test_rework_triggered, sm_story_review_triggered) to not be removed after post-actions completed. Affected: postPRReviewComments.js, postTestReviewComments.js, postTestReworkResults.js
- Add pr_discussions_raw.json to context list in pr_review_instructions.md so the regular PR review agent knows to read thread IDs - Add pr_discussions_raw.json to context list in pr_review_prompt.md with explicit instruction to populate resolvedThreadIds - Add Thread resolution rule to pr_test_review_instructions.md (was missing — only the JSON output format was referenced) Without these changes both reviewers would leave resolvedThreadIds empty on repeated reviews, causing threads to pile up across rework cycles. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- sm.json: add rule to trigger pr_rework.json for Stories in 'In Rework' with sm_story_rework_triggered idempotency label - pr_rework.json: add customParams.removeLabel = sm_story_rework_triggered - pushReworkChanges.js: remove SM idempotency label after rework completes so the ticket can be re-triggered in future cycles Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
New agent config and flow:
- bug_development.json: Teammate agent for bug fixing
- preCliJSAction: preCliDevelopmentSetup (checkout ai/BUG-XX branch, In Development)
- postJSAction: developBugAndCreatePR
- customParams.removeLabel: sm_bug_development_triggered
New post-action developBugAndCreatePR.js — three paths:
1. outputs/blocked.json exists → move to Blocked, post blocker reason
2. outputs/already_fixed.json exists → move to Ready For Testing, post commit ref
3. Neither → normal PR creation via developTicketAndCreatePR
New instructions/development/bug_implementation_instructions.md:
- Mandatory RCA before any code change (writes outputs/rca.md)
- Check if already fixed in recent commits (write already_fixed.json)
- Check if blocked / needs human (write blocked.json)
- Write failing unit test to reproduce bug before fixing
- Targeted minimal fix, verify with full test suite
New prompts/bug_development_prompt.md:
- Structured 7-step workflow: RCA → already-fixed check → blocked check
→ reproduce test → fix → verify → outputs/response.md
bug_merged.json + notifyBugMerged.js:
- Triggered by SM when Bug reaches Merged status
- Posts "ready for testing" comment, removes SM label
- SM targetStatus handles Ready For Testing transition
sm.json updates:
- Add rule: Ready For Development Bugs → bug_development.json
- Add rule: Merged Bugs → bug_merged.json (→ Ready For Testing)
- Expand In Review rule: Stories → Stories & Bugs (same pr_review.json)
- Expand In Rework rule: Stories → Stories & Bugs (same pr_rework.json)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Initial clone is now blobless (--filter=blob:none) so the full commit graph is already present. Branch fetches are near-instant because git only needs to download new blobs on demand, not negotiate history. Reverts the per-fetch depth/filter flags added in 02ec9b9 — they are no longer needed and --depth=1 would actually break rebase/merge-base. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Blobless clones (--filter=blob:none) are not shallow so calling git fetch --unshallow fails with exit 128 and pollutes logs with [ERROR] even though the catch handles it. Replace blind unshallow with a shallow check first: git rev-parse --is-shallow-repository → 'true' only for depth clones Applied in both getPRDiff and detectMergeConflicts. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…n diff) GitHub's inline comment API returns 422 when the target line is not inside a diff hunk. This happens when the reviewer comments on existing code that wasn't changed in this PR iteration. Instead of silently dropping those comments, fall back to a regular PR comment prefixed with the file:line reference so no feedback is lost. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…mment Threads from general PR review comments (REQUEST CHANGES reviews, summary comments) have rootCommentId/threadId = null. String(null) = 'null' was sent to github_reply_to_pr_thread, causing silent failures. Fix: if inReplyToId is null/undefined, post as a top-level PR comment instead of attempting an invalid thread reply. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add project_key resolution in triggerWorkflow: - rule.projectKey takes priority (explicit) - falls back to basename of configPath (e.g. configs/mapc.js → 'mapc') - passes as project_key in github_trigger_workflow inputs - logs [project_key=X] when set Also documents new projectKey rule field in header JSDoc. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
postPRReviewComments.js: - adds deriveProjectKey, buildAutoStartEncodedConfig, hasPrApprovedLabel helpers - after moving ticket to In Rework: if customParams.autoStartRework=true and autoStartReworkConfigFile is set, triggers ai-teammate.yml with the rework config; skips if ticket has pr_approved label pushReworkChanges.js: - adds same helpers + imports LABELS from config.js - after moving ticket to In Review: if customParams.autoStartReview=true and autoStartReviewConfigFile is set, triggers ai-teammate.yml with the review config; skips if ticket has pr_approved label Both use config.repository.owner/repo as the AI repo to trigger on. project_key is derived from customParams.projectKey or configPath basename. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
After ticket is moved to In Review: - if customParams.autoStartReview=true and autoStartReviewConfigFile is set, triggers ai-teammate.yml with the review config - skips if ticket already has pr_approved label - project_key derived from customParams.projectKey or configPath basename Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…eview customParams lives at params.jobParams.customParams in postJSAction context, not at params.customParams. Was reading wrong path → autoStartReview never fired. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
configLoader overrides config.repository with targetRepository (project repo), so auto-start was triggering on PostNL-commercial-mobileApp instead of PostNL-commercial-ai where ai-teammate.yml lives. All three auto-start scripts now prefer customParams.aiRepository when set, falling back to config.repository only when absent. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
New module fetchParentContextToInput.js: - Finds ticket's parent, searches siblings with [BA]/[SA]/[VD] prefix - Writes parent_context_ba.md, parent_context_sa.md, parent_context_vd.md - BA = Business Analysis (ACs, business rules, user flows) - SA = Solution Architecture (technical design, data model, API contracts) - VD = Visual Design (UI mockups, component specs) - Fully non-fatal: missing parent or no children → silent skip Integrated into all three MAPC pre-CLI setup scripts as last step: - preCliDevelopmentSetup.js (story_development) - preparePRForReview.js (pr_review) - preCliReworkSetup.js (pr_rework) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…omParams
Module is now a no-op when customParams.parentContextFetch is absent.
When present, all behaviour is driven by config:
- jql: JQL with {parentKey} placeholder (default: BA/SA/VD filter)
- fields: Jira fields to fetch (default: key, summary, description, status)
custom field IDs can be added; missing fields are re-fetched via jira_get_ticket
- contexts: array of {prefix, file, label, description} for matching and output
Defaults reproduce the original BA/SA/VD behaviour.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…Input - preCliSolutionSetup.js: chains fetchQuestionsToInput + fetchParentContextToInput for story_solution agent pre-CLI step - test_fetchParentContextToInput.js: 20 unit tests covering no-op guard, JQL placeholder replacement, context matching (case-insensitive), file content, re-fetch fallback for missing fields, and error resilience - run_fetchParentContextToInput.json: standalone runner for new tests - run_all.json: include new test file in full test suite Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add explicit steps 5-7 for parent_context_ba/sa/vd.md so the development agent reads them in priority order before implementing Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- pr_review_prompt.md: add parent_context_ba/sa/vd.md to context file list so reviewer checks implementation against BA ACs, SA design, VD specs - pr_rework_prompt.md: add parent_context_ba/sa/vd.md as steps 4-6 in reading order so rework agent has full parent context before applying fixes Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- renderFieldsMarkdown now accepts optional fieldLabels map for display names - fieldLabels resolved from cfg.fieldLabels (per-agent config) - Fixes rendering when JIRA_EXTRA_FIELDS is not set in CI environment Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- DEFAULT_FIELDS now includes 'comment' - renderCommentsMarkdown: renders comments as quoted markdown blocks with author, date, and body - renderFieldsMarkdown: special-cases 'comment' field via renderCommentsMarkdown Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Root cause of 422 errors: AI was using diff-position (line number within pr_diff.txt) instead of actual file line number from the @@ hunk header. - Explain exactly how to calculate line number from @@ header - Add concrete example: @@ -1344,6 +1344,9 @@ + 3 context lines = line 1347 - Recommend general comment fallback when line number is uncertain Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…uestions)
- New optional cfg.childQuestions: { jql, answerField } in parentContextFetch
- After writing each context file, JQL fetches [Q] children of that ticket
({contextTicketKey} replaced with actual key)
- Questions appended as '## Questions & Answers' section with Q/Answer format
- Non-fatal: any Q-fetch failure is warned and skipped
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CLI agents write outputs to outputs/{ticketKey}/response.md
instead of root outputs/response.md.
Add readOutput() helper: tries root path first, then ticket subdir fallback.
This fixes bug_rca (and any agent using writeSolutionAndDiagrams.js) silently
skipping Jira field updates when the file is in a subdirectory.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Agents were writing to outputs/{ticketKey}/response.md (subdir)
instead of outputs/response.md (root), causing silent Jira submission failure.
Add prominent warning block explaining exact required paths and
that subdirectories will cause the RCA to be silently discarded.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
9 recurring mistake categories extracted from closed review threads in PostNL-commercial-mobileApp PRs #918-934 (reviewers: dmytro-medvediuk-epam, pavel-kavalchuk-epam): 1. accessibilityRole enum vs raw strings (src/utils/helpers/accessibilityRoles.ts) 2. Scope discipline — only AC-required changes 3. Reuse existing components/utils/styles (flex1, getCountryFlagUrl, ModalDropdownPicker) 4. Project-wide accessibility fixes, not just changed files 5. Don't hide children of Pressable (accessible by default) 6. Never pass undefined to screen reader props — use empty string 7. Extract accessibility label logic to helper functions 8. Branch must be up-to-date with develop before PR 9. All styles in .styles.ts files — no inline createStyles in component files Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…n main repo Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…tructions Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- agents/instructions/common/investigate_before_answer.md: general instruction for agents to investigate current code/API before answering questions, to avoid guessing about what is already implemented - agents/instructions/product/po_domain_knowledge.md: describes dm.ai product context — CLI orchestration toolkit, 3-layer model (connectors, preCLI→AI→ postCLI, ready-made Jobs), key architecture facts, and how AI agents use DMtools Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Added sections for API surface (REST routes, MCP/@mcptool, OpenAPI specs) - Added CLI commands check (dmtools --help, @command annotations) - Added UI/UX check (React/Vue/Angular components, routes, Figma stories) - Removed po_domain_knowledge.md — moved to dm.ai project repo (.dmtools/instructions/) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Adds a JSRunner job that auto-generates a Confluence agent reference page from sm.json: - agents/js/agentDocSync.js — reads sm.json rules, deduplicates config refs, reads each config + prompt file, builds HTML table, publishes to Confluence (update or create) - agents/agent_doc_sync.json — JSRunner config template with customParams for confluenceSpace, confluencePageTitle, etc. Run with: ./dmtools.sh run agents/agent_doc_sync.json Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 930313b178
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| // 4. Fetch current page and update or create | ||
| var currentPage = fetchPage(pageId, pageTitle, space); | ||
| if (currentPage) { | ||
| var existingId = pageId || currentPage.id; |
There was a problem hiding this comment.
Use fetched page ID after title fallback
If confluencePageId is configured but stale/invalid, fetchPage() correctly falls back to confluence_find_content_by_title_and_space(...) and can return a valid page object, but this line still prefers the original pageId when calling confluence_update_page_with_history. In that case the update is attempted against the wrong ID and the sync fails even though the page was successfully found by title.
Useful? React with 👍 / 👎.
Summary
Adds a JSRunner job that auto-generates a Confluence agent reference page from
sm.json.Files
agents/js/agentDocSync.jssm.jsonto discover all registered agents (viaparams.jobParams.rules[])configFilereferences; skipslocalExecution: truerulescliPromptfile to extract action descriptionagents/agent_doc_sync.jsoncustomParams:smJsonPath,confluenceSpace,confluencePageTitle,confluencePageId,confluenceParentIdUsage
Fill in the
customParamsbefore running (space, title, optional page/parent IDs).Context
This PR is the DMtools side of epam/dm.ai#2, following maintainer feedback that this kind of automation belongs in a JSRunner job rather than AI-narrated CLI steps.