Skip to content

feat: Claude Code extended features — implement, doc sync, security, checklist, maintenance#109

Merged
Kavirubc merged 12 commits intomainfrom
feat/claude-code-extended-features
Mar 15, 2026
Merged

feat: Claude Code extended features — implement, doc sync, security, checklist, maintenance#109
Kavirubc merged 12 commits intomainfrom
feat/claude-code-extended-features

Conversation

@Kavirubc
Copy link
Copy Markdown
Contributor

@Kavirubc Kavirubc commented Mar 11, 2026

Summary

Extends the Claude Code integration with 5 new features, all configurable via .github/simili.yaml under claude_code:.

Depends on: #106 (base @simili-bot mention handler)
Closes: #108

Features

1. 🏗️ Issue Implementation

Label an issue with implement → Claude creates a branch and opens a PR with the implementation. Only OWNER/MEMBER/COLLABORATOR can trigger.

2. 📖 Doc Sync

When a PR changes files matching watch_paths (e.g., src/api/**), Claude auto-updates documentation in doc_paths.

3. 🔒 Security Review

Label a PR with security-review → Claude runs a focused OWASP-aligned security analysis. Only concrete findings, no filler — saves tokens.

4. ✅ Custom Review Checklist

Label a PR with review-checklist → Claude checks against user-defined checklist items from config.

5. 🔧 Scheduled Maintenance

Weekly cron or manual trigger → Claude runs configured maintenance tasks and creates a summary issue.

Configuration

claude_code:
  enabled: true

  issue_implement:
    enabled: true
    trigger_label: "implement"

  doc_sync:
    enabled: true
    watch_paths: ["src/api/**"]
    doc_paths: ["docs/"]

  security_review:
    enabled: true
    trigger_label: "security-review"

  review_checklist:
    enabled: true
    items:
      - "No hardcoded credentials"
      - "Unit tests for new functions"

  maintenance:
    enabled: true
    tasks:
      - "Check for outdated dependencies"
      - "Scan for TODO/FIXME comments"

Files Changed

Go Code

File Action Purpose
internal/core/config/config.go Modified ClaudeCodeConfig struct + 5 sub-configs, defaults, merge
internal/steps/claude_code_issue_implement.go New Issue implementation handler
internal/steps/claude_code_doc_sync.go New Doc sync handler + path matching
internal/steps/claude_code_review.go New Security review + review checklist
internal/steps/claude_code_maintenance.go New Scheduled maintenance handler
internal/steps/command_handler.go Modified Label/event routing + nil safety

Action & Workflow

File Action Purpose
action.yml Modified Added prompt and mode outputs
.github/workflows/triage.yml Modified Added labeled, schedule, workflow_dispatch triggers
DOCS/examples/single-repo/workflow.yml Modified Updated example

Commits (modular)

  1. feat(config) — ClaudeCodeConfig struct
  2. feat(handlers) — Issue implementation handler
  3. feat(handlers) — Doc sync handler
  4. feat(handlers) — Security review + review checklist handlers
  5. feat(handlers) — Scheduled maintenance handler
  6. feat(routing) — Command handler wiring
  7. feat(workflow) — Action outputs + triage workflow + nil fix

Testing

  • go build ./...
  • go test ./... ✅ (all packages)
  • go vet ./...
  • YAML lint ✅

Checklist

  • My code follows the project's style guidelines
  • I have performed a self-review of my code
  • I have commented my code, particularly in hard-to-understand areas
  • My changes generate no new warnings
  • New and existing unit tests pass locally with my changes

Summary by CodeRabbit

  • New Features

    • Claude Code can be triggered via labels on issues and pull requests.
    • Added documentation-sync, issue-implementation, security review, review-checklist, and maintenance Claude Code modes.
    • Scheduled (weekly) and manual workflow execution options added.
    • Claude Code now emits structured prompt and mode outputs when a feature triggers.
  • Chores

    • Expanded event filters and concurrency handling to improve trigger delivery and reduce conflicts.

Kavirubc added 10 commits March 11, 2026 15:22
- Add claude_code_handler.go: parses @simili-bot queries, validates
  author association (OWNER/MEMBER/COLLABORATOR), writes GitHub Actions
  outputs (claude_code_triggered, claude_code_query, claude_code_model_override)
- Modify command_handler.go: detect @simili-bot trigger before slash-commands
- Add CommentAuthorAssociation to pipeline Issue struct
- Extract author_association from GitHub event JSON in process.go
- Update action.yml with Claude Code outputs
- Update triage.yml with conditional claude-code-action step
- Update example workflow and setup docs
- Add CLAUDE.md for repo context

Users just add one extra step to their existing simili workflow +
the CLAUDE_CODE_OAUTH_TOKEN secret. No separate workflow file needed.

Closes #105

Signed-off-by: Kavirubc <hapuarachchikaviru@gmail.com>
…nd docs

Signed-off-by: Kavirubc <hapuarachchikaviru@gmail.com>
…atures

Adds configuration types for:
- Issue Implementation (label-triggered)
- Doc Sync (path-matched)
- Security Review (label-triggered)
- Custom Review Checklist
- Scheduled Maintenance

All features are opt-in via simili.yaml under claude_code: section.
Includes defaults, validation, and config inheritance merge logic.

Ref: #108
Signed-off-by: Kavirubc <hapuarachchikaviru@gmail.com>
When an issue is labeled with the trigger label (default: 'implement'),
validates the actor is an org OWNER/MEMBER/COLLABORATOR, builds a prompt
from the issue title + body, and signals Claude Code to create a PR.

Ref: #108
Signed-off-by: Kavirubc <hapuarachchikaviru@gmail.com>
When a PR changes files matching configured watch_paths (e.g., src/api/**),
builds a prompt instructing Claude Code to update documentation in doc_paths.
Includes glob matching with directory-level pattern support.

Ref: #108
Signed-off-by: Kavirubc <hapuarachchikaviru@gmail.com>
Security review: triggered by label (default: 'security-review'),
runs a focused OWASP-aligned analysis with severity ratings —
only concrete findings, no filler to save tokens.

Review checklist: triggered by label (default: 'review-checklist'),
checks the PR against user-defined checklist items from simili.yaml.

Ref: #108
Signed-off-by: Kavirubc <hapuarachchikaviru@gmail.com>
Processes schedule/workflow_dispatch events, builds a prompt from
configured maintenance tasks, and instructs Claude to create a summary
issue with actionable findings only.

Ref: #108
Signed-off-by: Kavirubc <hapuarachchikaviru@gmail.com>
Adds checkClaudeCodeLabelTriggers() to route:
- issues.labeled → issue_implement handler
- pull_request.labeled → security_review / review_checklist
- pull_request.opened/synchronize → doc_sync (path matching)
- schedule/workflow_dispatch → maintenance handler

All routing gated behind claude_code.enabled and per-feature enabled flags.
Adds hasLabel() helper for case-insensitive label matching.

Ref: #108
Signed-off-by: Kavirubc <hapuarachchikaviru@gmail.com>
… Claude Code features

- action.yml: add claude_code_prompt and claude_code_mode outputs
- triage.yml: add issues.labeled, pull_request.labeled/synchronize,
  schedule, and workflow_dispatch triggers
- Example workflow: updated with new triggers and prompt pass-through
- Fix nil pointer dereference when ctx.Config is nil in tests

Ref: #108
Signed-off-by: Kavirubc <hapuarachchikaviru@gmail.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 11, 2026

📝 Walkthrough

Walkthrough

Adds a configurable "Claude Code" feature set (issue-implement, doc-sync, security-review, review-checklist, maintenance): new config schema, new CommandHandler routing and handlers that detect triggers, build prompts, emit GitHub Action outputs, and workflow updates to invoke Claude Code steps.

Changes

Cohort / File(s) Summary
Workflows / Examples
.github/workflows/triage.yml, DOCS/examples/single-repo/workflow.yml
Added weekly schedule and workflow_dispatch triggers, expanded issue/pull_request event types (including labeled, synchronize, ready_for_review), adjusted concurrency, and pass claude_code_prompt into Claude Code action.
Action outputs
action.yml
Updated output descriptions; added claude_code_prompt and claude_code_mode outputs.
Configuration
internal/core/config/config.go
Added ClaudeCodeConfig and nested structs (IssueImplement, DocSync, SecurityReview, ReviewChecklist, Maintenance), included in top-level Config, with defaults and merge propagation.
Claude Code handlers
internal/steps/claude_code_doc_sync.go, internal/steps/claude_code_issue_implement.go, internal/steps/claude_code_maintenance.go, internal/steps/claude_code_review.go
New handlers for doc-sync, issue-implement, maintenance, security-review, and review-checklist: each builds a prompt, writes claude_code_triggered, claude_code_prompt, and claude_code_mode, then returns ErrSkipPipeline. Doc-sync adds path-globbing helpers.
Command routing / integration
internal/steps/command_handler.go, cmd/simili/commands/process.go, internal/core/pipeline/pipeline.go
Added label-aware event parsing (AddedLabel), new Issue.AddedLabel field, and checkClaudeCodeLabelTriggers + helpers in CommandHandler; routes label/schedule/dispatch triggers to the new handlers before prior analysis.

Sequence Diagram(s)

sequenceDiagram
    participant GH as "GitHub Event"
    participant CH as "CommandHandler"
    participant CFG as "Config (ClaudeCodeConfig)"
    participant OUT as "GitHub Outputs"
    participant CLAUDE as "Claude Code Action"

    GH->>CH: deliver event (label / PR open/sync / schedule / dispatch)
    CH->>CFG: read ClaudeCode config
    CFG-->>CH: feature settings
    alt Label-trigger (issue / PR)
        CH->>CH: validate auth/label, build prompt
    else Doc Sync (PR changed files)
        CH->>CH: match changed files → watch_paths, build prompt
    else Scheduled Maintenance
        CH->>CH: build maintenance task prompt
    end
    CH->>OUT: set `claude_code_triggered=true`
    CH->>OUT: set `claude_code_prompt=<prompt>`
    CH->>OUT: set `claude_code_mode=<mode>`
    OUT-->>CLAUDE: prompt consumed by Claude Code step
    CH->>CH: return ErrSkipPipeline
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

bot, ci/cd

Suggested reviewers

  • gh-simili-bot

Poem

🐰 I nibble labels, hop through code and docs so bright,
Prompts stitched like carrots, ready for the night,
I sync the docs, check security with care,
Maintain the tasks, and tidy up with flair,
A rabbit's cheer for features taking flight!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely summarizes the main change: extending Claude Code with five new configurable features (implement, doc sync, security, checklist, maintenance).
Linked Issues check ✅ Passed The PR implements all five required features from issue #108: Issue Implementation with authorization checks, Doc Sync with path matching, Security Review with focused analysis, Custom Review Checklist with user-defined items, and Scheduled Maintenance with cron triggers, all configurable via ClaudeCodeConfig.
Out of Scope Changes check ✅ Passed All changes align with the PR objectives: new config structures, handler implementations, workflow updates, and pipeline enhancements directly support the five Claude Code features specified in issue #108.
Docstring Coverage ✅ Passed Docstring coverage is 85.71% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/claude-code-extended-features

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@gh-simili-bot
Copy link
Copy Markdown
Contributor

Simili Triage Report

Note

Quality Score: 8.8/10 (Good)
The issue could be improved. See suggestions below.

Classification

Category Value
Labels
Quality Improvements
  • Configuration example is truncated
  • Provide the full YAML configuration snippet for claude_code: to illustrate how these features will be configured.
Similar Threads
Similarity Type Thread Status
93% 📝 #108 feat: Claude Code extended features — Issue Imp... Open
87% 🔀 #106 feat: integrate Claude Code @simili-bot for AI-... Open
84% 📝 #105 feat: Add Claude Code GitHub Action for AI-assi... Open

Warning

Possible Duplicate (Confidence: 98%)
This pull request might be a duplicate of #108.
Reason: The current issue explicitly states 'Closes: #108' and describes the exact same set of five extended features (Issue Implementation, Doc Sync, Security Review, Custom Review Checklist, Scheduled Maintenance) as listed in the title of Issue #108. This indicates that Issue #108 is a direct duplicate or a superseded version of the same feature request. Issue #106 is related because the current issue 'Depends on: #106', meaning #106 is a foundational prerequisite for the extended features, not the same problem itself. Issue #105 is also related as it describes adding the core Claude Code GitHub Action for AI-assisted PR fixes, which is a different problem (initial integration mechanism) than the extended features described in the current issue.
Also related to: #106 (feat: integrate Claude Code @simili-bot for AI-assisted PR fixes), #105 (feat: Add Claude Code GitHub Action for AI-assisted PR fixes via @simili-bot comments)

This pull request will be automatically closed in 72 hours if no objections are raised. If you believe this is not a duplicate, please leave a comment explaining why.


Generated by Simili Bot

@gh-simili-bot gh-simili-bot added ai enhancement New feature or request feature labels Mar 11, 2026
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (5)
internal/steps/claude_code_issue_implement.go (1)

38-42: Handle writeGitHubOutput errors consistently.

Same pattern as other handlers — add warning logs for consistency.

♻️ Proposed fix to add warning logs
-	writeGitHubOutput("claude_code_triggered", "true")
-	writeGitHubOutput("claude_code_prompt", prompt)
-	writeGitHubOutput("claude_code_mode", "issue_implement")
+	if err := writeGitHubOutput("claude_code_triggered", "true"); err != nil {
+		log.Printf("[command_handler] Warning: failed to write GITHUB_OUTPUT: %v", err)
+	}
+	if err := writeGitHubOutput("claude_code_prompt", prompt); err != nil {
+		log.Printf("[command_handler] Warning: failed to write GITHUB_OUTPUT: %v", err)
+	}
+	if err := writeGitHubOutput("claude_code_mode", "issue_implement"); err != nil {
+		log.Printf("[command_handler] Warning: failed to write GITHUB_OUTPUT: %v", err)
+	}

 	return pipeline.ErrSkipPipeline
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@internal/steps/claude_code_issue_implement.go` around lines 38 - 42, The
three writeGitHubOutput calls in claude_code_issue_implement.go currently ignore
returned errors; update the function to check each writeGitHubOutput(...) error
and, on failure, emit a warning log (e.g., using the same logger used in other
handlers) while continuing execution, so that
writeGitHubOutput("claude_code_triggered", ...),
writeGitHubOutput("claude_code_prompt", ...), and
writeGitHubOutput("claude_code_mode", ...) each handle and log errors
consistently with other handlers.
internal/steps/claude_code_doc_sync.go (1)

44-68: Consider logging malformed glob patterns.

filepath.Match errors (from ok, _ :=) are silently discarded. While this only occurs for malformed patterns (not runtime failures), logging would help users debug invalid watch_paths configuration.

🔧 Optional: log pattern errors for debuggability
 func matchesDocSyncPaths(changedFiles []string, watchPaths []string) []string {
 	var matched []string
 	for _, file := range changedFiles {
 		for _, pattern := range watchPaths {
-			if ok, _ := filepath.Match(pattern, file); ok {
+			ok, err := filepath.Match(pattern, file)
+			if err != nil {
+				log.Printf("[doc_sync] Warning: invalid glob pattern %q: %v", pattern, err)
+				continue
+			}
+			if ok {
 				matched = append(matched, file)
 				break
 			}
 			// Also try matching just the filename against the pattern
 			// for patterns like "*.go"
-			if ok, _ := filepath.Match(pattern, filepath.Base(file)); ok {
+			ok, err = filepath.Match(pattern, filepath.Base(file))
+			if err != nil {
+				// Already logged above for same pattern
+				continue
+			}
+			if ok {
 				matched = append(matched, file)
 				break
 			}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@internal/steps/claude_code_doc_sync.go` around lines 44 - 68, In
matchesDocSyncPaths, filepath.Match errors are ignored; change the two places
using "if ok, _ := filepath.Match(...)" to capture the error (ok, err :=
filepath.Match(...)) and when err != nil log the malformed pattern and the
file/filename being tested (include the pattern string from watchPaths and the
file variable) so users can debug invalid watch_paths; ensure you use the
project's logging facility (or log.Printf if none) and continue to skip the
match on error rather than panicking.
internal/steps/claude_code_maintenance.go (1)

43-47: Handle writeGitHubOutput errors consistently.

Same pattern as other handlers — add warning logs for consistency with handleClaudeCodeTrigger.

♻️ Proposed fix to add warning logs
-	writeGitHubOutput("claude_code_triggered", "true")
-	writeGitHubOutput("claude_code_prompt", prompt)
-	writeGitHubOutput("claude_code_mode", "maintenance")
+	if err := writeGitHubOutput("claude_code_triggered", "true"); err != nil {
+		log.Printf("[command_handler] Warning: failed to write GITHUB_OUTPUT: %v", err)
+	}
+	if err := writeGitHubOutput("claude_code_prompt", prompt); err != nil {
+		log.Printf("[command_handler] Warning: failed to write GITHUB_OUTPUT: %v", err)
+	}
+	if err := writeGitHubOutput("claude_code_mode", "maintenance"); err != nil {
+		log.Printf("[command_handler] Warning: failed to write GITHUB_OUTPUT: %v", err)
+	}

 	return pipeline.ErrSkipPipeline
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@internal/steps/claude_code_maintenance.go` around lines 43 - 47, The three
calls to writeGitHubOutput ("claude_code_triggered", "claude_code_prompt",
"claude_code_mode") currently ignore returned errors; update this block to check
each writeGitHubOutput error and emit a warning log in the same style as
handleClaudeCodeTrigger (use the same logger/warning method used there) when a
write fails, including which key failed and the error, then return
pipeline.ErrSkipPipeline as before.
internal/steps/claude_code_review.go (2)

42-46: Handle writeGitHubOutput errors consistently.

The return values from writeGitHubOutput are ignored here, but the function can fail when opening or writing to the GITHUB_OUTPUT file. The existing handleClaudeCodeTrigger in claude_code_handler.go (lines 51-62) logs warnings on failure. Apply the same pattern for consistency and debuggability.

♻️ Proposed fix to add warning logs
-	writeGitHubOutput("claude_code_triggered", "true")
-	writeGitHubOutput("claude_code_prompt", prompt)
-	writeGitHubOutput("claude_code_mode", "security_review")
+	if err := writeGitHubOutput("claude_code_triggered", "true"); err != nil {
+		log.Printf("[command_handler] Warning: failed to write GITHUB_OUTPUT: %v", err)
+	}
+	if err := writeGitHubOutput("claude_code_prompt", prompt); err != nil {
+		log.Printf("[command_handler] Warning: failed to write GITHUB_OUTPUT: %v", err)
+	}
+	if err := writeGitHubOutput("claude_code_mode", "security_review"); err != nil {
+		log.Printf("[command_handler] Warning: failed to write GITHUB_OUTPUT: %v", err)
+	}

 	return pipeline.ErrSkipPipeline
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@internal/steps/claude_code_review.go` around lines 42 - 46, The three calls
to writeGitHubOutput (writeGitHubOutput("claude_code_triggered", ...),
writeGitHubOutput("claude_code_prompt", ...),
writeGitHubOutput("claude_code_mode", ...)) currently ignore returned errors;
change each to capture the error and, on non-nil error, log a warning consistent
with handleClaudeCodeTrigger in claude_code_handler.go (use the same logger and
message style), e.g. if err := writeGitHubOutput(...); err != nil {
logger.Warnf("failed to write GITHUB_OUTPUT for %s: %v", "<key>", err) }, then
proceed to return pipeline.ErrSkipPipeline as before.

77-81: Handle writeGitHubOutput errors consistently.

Same issue as handleSecurityReviewTrigger — the error returns are ignored. Add warning logs for consistency with handleClaudeCodeTrigger.

♻️ Proposed fix to add warning logs
-	writeGitHubOutput("claude_code_triggered", "true")
-	writeGitHubOutput("claude_code_prompt", prompt)
-	writeGitHubOutput("claude_code_mode", "review_checklist")
+	if err := writeGitHubOutput("claude_code_triggered", "true"); err != nil {
+		log.Printf("[command_handler] Warning: failed to write GITHUB_OUTPUT: %v", err)
+	}
+	if err := writeGitHubOutput("claude_code_prompt", prompt); err != nil {
+		log.Printf("[command_handler] Warning: failed to write GITHUB_OUTPUT: %v", err)
+	}
+	if err := writeGitHubOutput("claude_code_mode", "review_checklist"); err != nil {
+		log.Printf("[command_handler] Warning: failed to write GITHUB_OUTPUT: %v", err)
+	}

 	return pipeline.ErrSkipPipeline
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@internal/steps/claude_code_review.go` around lines 77 - 81, The three
writeGitHubOutput calls ignore returned errors; update them to capture each
error and log a warning (using the same logger and logging style as
handleClaudeCodeTrigger/handleSecurityReviewTrigger) when writeGitHubOutput
returns non-nil, e.g. check err := writeGitHubOutput(...) and call
logger.Warnf("writeGitHubOutput(%s) failed: %v", key, err) for
"claude_code_triggered", "claude_code_prompt", and "claude_code_mode", but still
return pipeline.ErrSkipPipeline as before.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@internal/steps/claude_code_doc_sync.go`:
- Around line 35-39: The three calls to writeGitHubOutput (for
"claude_code_triggered", "claude_code_prompt", "claude_code_mode") currently
ignore returned errors; update claude_code_doc_sync.go to check each error and,
on non-nil error, log a warning consistent with the pattern used in
handleClaudeCodeTrigger in claude_code_handler.go (use the same logger and
warning message style), then continue to the return pipeline.ErrSkipPipeline so
behavior is unchanged but errcheck is satisfied.

In `@internal/steps/command_handler.go`:
- Around line 128-145: The conditional that gates label-triggered handlers
incorrectly includes "pr_comment"; update the check in command_handler.go so it
only checks ctx.Issue.EventType == "pull_request" (remove "pr_comment") before
testing ctx.Issue.EventAction == "labeled", leaving the subsequent hasLabel
checks and calls to s.handleSecurityReviewTrigger and
s.handleReviewChecklistTrigger unchanged (retain cc.SecurityReview.Enabled,
cc.ReviewChecklist.Enabled and hasLabel usage).

---

Nitpick comments:
In `@internal/steps/claude_code_doc_sync.go`:
- Around line 44-68: In matchesDocSyncPaths, filepath.Match errors are ignored;
change the two places using "if ok, _ := filepath.Match(...)" to capture the
error (ok, err := filepath.Match(...)) and when err != nil log the malformed
pattern and the file/filename being tested (include the pattern string from
watchPaths and the file variable) so users can debug invalid watch_paths; ensure
you use the project's logging facility (or log.Printf if none) and continue to
skip the match on error rather than panicking.

In `@internal/steps/claude_code_issue_implement.go`:
- Around line 38-42: The three writeGitHubOutput calls in
claude_code_issue_implement.go currently ignore returned errors; update the
function to check each writeGitHubOutput(...) error and, on failure, emit a
warning log (e.g., using the same logger used in other handlers) while
continuing execution, so that writeGitHubOutput("claude_code_triggered", ...),
writeGitHubOutput("claude_code_prompt", ...), and
writeGitHubOutput("claude_code_mode", ...) each handle and log errors
consistently with other handlers.

In `@internal/steps/claude_code_maintenance.go`:
- Around line 43-47: The three calls to writeGitHubOutput
("claude_code_triggered", "claude_code_prompt", "claude_code_mode") currently
ignore returned errors; update this block to check each writeGitHubOutput error
and emit a warning log in the same style as handleClaudeCodeTrigger (use the
same logger/warning method used there) when a write fails, including which key
failed and the error, then return pipeline.ErrSkipPipeline as before.

In `@internal/steps/claude_code_review.go`:
- Around line 42-46: The three calls to writeGitHubOutput
(writeGitHubOutput("claude_code_triggered", ...),
writeGitHubOutput("claude_code_prompt", ...),
writeGitHubOutput("claude_code_mode", ...)) currently ignore returned errors;
change each to capture the error and, on non-nil error, log a warning consistent
with handleClaudeCodeTrigger in claude_code_handler.go (use the same logger and
message style), e.g. if err := writeGitHubOutput(...); err != nil {
logger.Warnf("failed to write GITHUB_OUTPUT for %s: %v", "<key>", err) }, then
proceed to return pipeline.ErrSkipPipeline as before.
- Around line 77-81: The three writeGitHubOutput calls ignore returned errors;
update them to capture each error and log a warning (using the same logger and
logging style as handleClaudeCodeTrigger/handleSecurityReviewTrigger) when
writeGitHubOutput returns non-nil, e.g. check err := writeGitHubOutput(...) and
call logger.Warnf("writeGitHubOutput(%s) failed: %v", key, err) for
"claude_code_triggered", "claude_code_prompt", and "claude_code_mode", but still
return pipeline.ErrSkipPipeline as before.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 1521352c-608f-4c6a-a807-2a988bab0162

📥 Commits

Reviewing files that changed from the base of the PR and between a42a602 and f8808ff.

📒 Files selected for processing (9)
  • .github/workflows/triage.yml
  • DOCS/examples/single-repo/workflow.yml
  • action.yml
  • internal/core/config/config.go
  • internal/steps/claude_code_doc_sync.go
  • internal/steps/claude_code_issue_implement.go
  • internal/steps/claude_code_maintenance.go
  • internal/steps/claude_code_review.go
  • internal/steps/command_handler.go

@Kavirubc
Copy link
Copy Markdown
Contributor Author

@simili-bot Fix the coderabbit and LINT errors and add a commit to the PR

@claude
Copy link
Copy Markdown

claude bot commented Mar 11, 2026

Claude finished @Kavirubc's task in 1m 58s —— View job


Fixed CodeRabbit and LINT Errors

All issues identified by CodeRabbit and the errcheck linter have been resolved.

Tasks completed:

  • Read affected files to understand current code
  • Fix writeGitHubOutput error handling in claude_code_doc_sync.go
  • Fix glob pattern error logging in claude_code_doc_sync.go
  • Fix writeGitHubOutput error handling in claude_code_issue_implement.go
  • Fix writeGitHubOutput error handling in claude_code_maintenance.go
  • Fix writeGitHubOutput error handling in claude_code_review.go (2 locations)
  • Remove pr_comment from labeled action check in command_handler.go
  • Commit and push changes (a00f9c1)

Changes made

errcheck lint fixes — all 5 handler files now check writeGitHubOutput errors and log warnings on failure, consistent with the pattern in handleClaudeCodeTrigger:

  • claude_code_doc_sync.go — 3 output writes now error-checked
  • claude_code_issue_implement.go — 3 output writes now error-checked
  • claude_code_maintenance.go — 3 output writes now error-checked
  • claude_code_review.go — 6 output writes now error-checked (2 functions)

Dead code fixcommand_handler.go:129: Removed pr_comment from the PR labeled action check. The issue_comment webhook (which maps to pr_comment) only fires created/edited/deleted actions — never labeled. The condition was unreachable.

Glob pattern loggingclaude_code_doc_sync.go: matchesDocSyncPaths now captures and logs errors from filepath.Match instead of silently discarding them, making invalid watch_paths config easier to debug.
| Branch: feat/claude-code-extended-features

… trigger check

- Check and log errors from writeGitHubOutput in all Claude Code handlers
  (doc_sync, issue_implement, maintenance, security_review, review_checklist)
  to satisfy errcheck linter requirements
- Log malformed glob patterns in matchesDocSyncPaths for debuggability
- Remove pr_comment from PR labeled action check (dead code: issue_comment
  events never have labeled action)

Co-authored-by: Kaviru Hapuarachchi <Kavirubc@users.noreply.github.com>
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@internal/steps/claude_code_doc_sync.go`:
- Around line 54-80: The current matching loop uses filepath.Match and a manual
suffix check (see filepath.Match usage and the strings.HasSuffix(pattern, "/**")
branch) which does not support recursive doublestar patterns like "**"; replace
this logic by using a doublestar-compatible matcher (e.g.,
github.com/bmatcuk/doublestar's Match or PathMatch) to test patterns against
file and filepath.Base(file), remove the ad-hoc "/**" special-case, and update
imports accordingly so patterns like "internal/**/*.go" and "docs/**/README.md"
correctly add entries to the matched slice.

In `@internal/steps/command_handler.go`:
- Around line 119-143: The handlers currently check ctx.Issue.Labels (the full
label set) which causes retriggers; instead read the event’s added-label field
from the payload (e.g., a dedicated ctx.Issue.AddedLabel or ctx.Issue.LabelName
provided by the webhook) and compare that single added label to each trigger via
direct equality (not hasLabel on the full slice) before calling
handleIssueImplementTrigger, handleSecurityReviewTrigger, or
handleReviewChecklistTrigger; keep the existing EventType/EventAction checks but
replace hasLabel(ctx.Issue.Labels, ...) with a direct match against the
added-label value so only the newly added label fires the corresponding handler.
- Around line 149-154: The Doc Sync gate currently only checks
cc.DocSync.WatchPaths which can allow triggering when no destination doc paths
are configured; add a guard that ensures cc.DocSync.DocPaths (or the field
representing configured destination doc paths) is non-empty before proceeding:
inside the block that checks cc.DocSync.Enabled and cc.DocSync.WatchPaths,
verify that cc.DocSync.DocPaths != nil and len(cc.DocSync.DocPaths) > 0 (or the
equivalent field name), and only then call matchesDocSyncPaths(...) and return
s.handleDocSyncTrigger(ctx, matched) when matched is non-empty. This change
should reference cc.DocSync.Enabled, cc.DocSync.WatchPaths, cc.DocSync.DocPaths
(or the actual doc_paths field name), matchesDocSyncPaths, and
handleDocSyncTrigger.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 0cefc898-3360-44f2-a0d3-0f309607c0f9

📥 Commits

Reviewing files that changed from the base of the PR and between f8808ff and a00f9c1.

📒 Files selected for processing (5)
  • internal/steps/claude_code_doc_sync.go
  • internal/steps/claude_code_issue_implement.go
  • internal/steps/claude_code_maintenance.go
  • internal/steps/claude_code_review.go
  • internal/steps/command_handler.go
🚧 Files skipped from review as they are similar to previous changes (2)
  • internal/steps/claude_code_issue_implement.go
  • internal/steps/claude_code_review.go

@Kavirubc
Copy link
Copy Markdown
Contributor Author

@simili-bot Look into the recent comments added by code rabbit. And also ensure that CI tests will pass as well when pushing into this PR.

@claude
Copy link
Copy Markdown

claude bot commented Mar 12, 2026

Claude finished @Kavirubc's task in 5m 27s —— View job


CodeRabbit Fixes — 3 Issues Resolved

All 3 actionable issues from CodeRabbit's second review have been fixed in commit 30aa750.


Changes made

Fix 1 — Doublestar glob support (internal/steps/claude_code_doc_sync.go)

filepath.Match does not support ** recursive patterns. Replaced matchesDocSyncPaths with a proper implementation:

  • Added matchGlob(pattern, file string) (bool, error) — fast-path to filepath.Match when no ** is present, otherwise delegates to the recursive matcher
  • Added matchDoublestarParts(patParts, pathParts []string) bool — recursively matches path segments, where ** consumes zero or more directory segments
  • Removed the ad-hoc strings.HasSuffix(pattern, "/**") special-case (now handled correctly by the general ** logic)
  • Patterns like src/api/**, internal/**/*.go, and docs/**/README.md now work correctly

Fix 2 — Match only the newly-added label (internal/core/pipeline/pipeline.go, cmd/simili/commands/process.go, internal/steps/command_handler.go)

On labeled events, checking ctx.Issue.Labels (full list) caused re-triggers whenever any label was added to a PR that already had a trigger label:

  • Added AddedLabel string field to pipeline.Issue to carry the specific label from the webhook
  • enrichIssueFromGitHubEvent now extracts raw["label"]["name"] into issue.AddedLabel
  • Added labelTriggered(issue, target) helper in command_handler.go — uses exact match on AddedLabel when available, falls back to hasLabel for backward compatibility (e.g. tests)
  • All three label trigger call-sites (IssueImplement, SecurityReview, ReviewChecklist) now use labelTriggered

Fix 3 — Guard Doc Sync when doc_paths is empty (internal/steps/command_handler.go)

Doc Sync was triggering even when doc_paths was not configured, producing an unscoped prompt. Added len(cc.DocSync.DocPaths) > 0 to the existing guard condition:

if cc.DocSync.Enabled != nil && *cc.DocSync.Enabled &&
    len(cc.DocSync.WatchPaths) > 0 && len(cc.DocSync.DocPaths) > 0 {

Files changed

File Change
internal/steps/claude_code_doc_sync.go Doublestar glob support (matchGlob + matchDoublestarParts)
internal/steps/command_handler.go labelTriggered helper + doc_paths guard
internal/core/pipeline/pipeline.go Added AddedLabel field to Issue struct
cmd/simili/commands/process.go Extract added label from webhook payload

Note: go build/go test/go vet require tool approval in this environment — CI will verify the build on push.
| Branch: feat/claude-code-extended-features

…_paths guard

- claude_code_doc_sync.go: replace filepath.Match with matchGlob/matchDoublestarParts
  helpers that support ** recursive patterns (e.g. src/api/**/*.go)
- pipeline.go: add AddedLabel field to Issue for the newly-added label on labeled events
- process.go: extract raw["label"]["name"] into issue.AddedLabel in enrichIssueFromGitHubEvent
- command_handler.go: add labelTriggered helper that matches only the added label
  when available (prevents retriggers when unrelated labels are added later);
  add len(cc.DocSync.DocPaths) > 0 guard before triggering doc sync

Co-authored-by: Kaviru Hapuarachchi <Kavirubc@users.noreply.github.com>
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@internal/steps/command_handler.go`:
- Around line 146-159: The DocSync trigger never sees changed files because
ctx.Metadata["changed_files"] is never populated; update the payload enrichment
so pull-request file names are extracted and stored, or ensure
ListPullRequestFiles is invoked early to set ctx.Metadata["changed_files"]
before command handling. Specifically, modify enrichIssueFromGitHubEvent or
populateIssuePayload to parse the webhook PR payload's files array (or call
ListPullRequestFiles in the gatekeeper/initialization step) and populate
ctx.Metadata["changed_files"] with []string so matchesDocSyncPaths and
handleDocSyncTrigger can run as intended.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 844f92b4-de5e-490b-8a83-8b1c0ab52fa5

📥 Commits

Reviewing files that changed from the base of the PR and between a00f9c1 and 30aa750.

📒 Files selected for processing (4)
  • cmd/simili/commands/process.go
  • internal/core/pipeline/pipeline.go
  • internal/steps/claude_code_doc_sync.go
  • internal/steps/command_handler.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • internal/steps/claude_code_doc_sync.go

Comment on lines +146 to +159
// Doc Sync: PR opened/updated that changes watched paths.
if ctx.Issue.EventType == "pull_request" &&
(ctx.Issue.EventAction == "opened" || ctx.Issue.EventAction == "synchronize") {
if cc.DocSync.Enabled != nil && *cc.DocSync.Enabled &&
len(cc.DocSync.WatchPaths) > 0 && len(cc.DocSync.DocPaths) > 0 {
// Changed files are passed via metadata from the event payload.
if changedFiles, ok := ctx.Metadata["changed_files"].([]string); ok && len(changedFiles) > 0 {
matched := matchesDocSyncPaths(changedFiles, cc.DocSync.WatchPaths)
if len(matched) > 0 {
return s.handleDocSyncTrigger(ctx, matched)
}
}
}
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Search for where ctx.Metadata["changed_files"] is set

# Search for assignments to changed_files in Metadata
rg -n 'Metadata\[.*changed_files' --type=go -C3

# Also search for any GitHub API call that fetches PR files
rg -n 'ListFiles|GetPullRequestFiles|changed.*files' --type=go -C3

Repository: similigh/simili-bot

Length of output: 3762


🏁 Script executed:

#!/bin/bash
# Search for where ctx.Metadata is assigned (broader pattern)
echo "=== Looking for metadata assignments ==="
rg -n 'ctx\.Metadata\[' --type=go -B2 -A2 | head -50

echo ""
echo "=== Looking for Metadata map initialization or assignment ==="
rg -n 'Metadata.*=' --type=go -B1 -A1

echo ""
echo "=== Checking if ListPullRequestFiles is called in event handling ==="
rg -n 'ListPullRequestFiles|PopulateMetadata|changed.*files.*Metadata' --type=go -C2

Repository: similigh/simili-bot

Length of output: 8749


🏁 Script executed:

#!/bin/bash
# Search for webhook/event payload parsing
echo "=== Looking for event payload parsing ==="
rg -n 'github.*payload|webhook|event.*payload' --type=go -i -C2 | head -60

echo ""
echo "=== Searching for files that might initialize ctx.Metadata ==="
rg -n 'ctx\.Metadata\s*=' --type=go -B3 -A3

echo ""
echo "=== Check if there's a main/webhook handler ==="
fd -e go -path '*/main.go' -o -path '*/handler.go' -o -path '*/webhook.go' | xargs ls -la 2>/dev/null

echo ""
echo "=== Search all references to changed_files ==="
rg -n 'changed_files' --type=go

Repository: similigh/simili-bot

Length of output: 3578


🏁 Script executed:

#!/bin/bash
echo "=== Checking cmd/ directory structure ==="
find cmd -name "*.go" -exec echo "File: {}" \; -exec wc -l {} \;

echo ""
echo "=== Search for ctx.Metadata initialization or PR files handling ==="
rg -n 'func.*Context|Metadata.*make|NewContext|changed.*files' cmd/ --type=go -B2 -A5

echo ""
echo "=== Check if there's any pre-processing before steps ==="
rg -n 'Pull.*Request|PR.*files|changed' cmd/ --type=go -i

Repository: similigh/simili-bot

Length of output: 1829


🏁 Script executed:

#!/bin/bash
echo "=== Find pipeline package ==="
find . -name "*.go" -path "*/pipeline/*" | head -20

echo ""
echo "=== Check for NewContext function ==="
rg -n 'func NewContext|type Context struct' --type=go -A20 | head -80

Repository: similigh/simili-bot

Length of output: 2909


🏁 Script executed:

#!/bin/bash
echo "=== Check Issue struct definition ==="
rg -n 'type Issue struct' --type=go -A30

echo ""
echo "=== Check where steps are registered and their order ==="
rg -n 'RegisterAll|register.*command_handler|register.*DocSync' --type=go -B2 -A2

echo ""
echo "=== Check if any step fetches PR files before command_handler ==="
rg -n 'ListPullRequestFiles|fetch.*files|get.*changed' --type=go -B3 -A3

Repository: similigh/simili-bot

Length of output: 4158


🏁 Script executed:

#!/bin/bash
echo "=== Read full register.go to see step order ==="
cat internal/steps/register.go

echo ""
echo "=== Search for webhook payload parsing or PR files extraction ==="
rg -n 'pull.*request|webhook.*payload|changed.*file' cmd/simili-web/main.go --type=go -B3 -A3 -i

Repository: similigh/simili-bot

Length of output: 2190


🏁 Script executed:

#!/bin/bash
echo "=== Check gatekeeper step ==="
rg -n 'type Gatekeeper|func.*Gatekeeper' internal/steps/gatekeeper.go --type=go -A20 | head -60

echo ""
echo "=== Check main.go for webhook/payload handling ==="
cat cmd/simili-web/main.go | head -150

Repository: similigh/simili-bot

Length of output: 6704


🏁 Script executed:

#!/bin/bash
echo "=== Look for webhook handler or GitHub event processing ==="
rg -n 'pull_request|webhook|PullRequest.*Event' cmd/ --type=go -B2 -A5

echo ""
echo "=== Search for GitHub webhook parsing in internal/ ==="
rg -n 'X-GitHub-Event|webhook.*payload|pull.*request.*event' internal/ --type=go -i -C3 | head -80

echo ""
echo "=== Check cmd/simili/commands/process.go for webhook handling ==="
head -100 cmd/simili/commands/process.go

Repository: similigh/simili-bot

Length of output: 9215


🏁 Script executed:

#!/bin/bash
echo "=== Continue reading process.go to find Issue creation ==="
sed -n '100,250p' cmd/simili/commands/process.go

echo ""
echo "=== Search for where Issue struct is populated from GitHub webhook ==="
rg -n 'Issue{|EventType.*pull_request|ParseWebhook|payload' cmd/ internal/ --type=go -B2 -A3 | head -100

Repository: similigh/simili-bot

Length of output: 4408


🏁 Script executed:

#!/bin/bash
echo "=== Find enrichIssueFromGitHubEvent function ==="
rg -n 'enrichIssueFromGitHubEvent|githubIssueToPipelineIssue' cmd/simili/commands/process.go --type=go -A50 | head -150

echo ""
echo "=== Search for changed_files in any GitHub event parsing ==="
rg -n 'changed_files|Changed|PullRequest.*Files' cmd/ internal/ --type=go -B2 -A2

Repository: similigh/simili-bot

Length of output: 6746


🏁 Script executed:

#!/bin/bash
echo "=== Read complete enrichIssueFromGitHubEvent function ==="
sed -n '343,450p' cmd/simili/commands/process.go

Repository: similigh/simili-bot

Length of output: 3330


The DocSync trigger will never activate — changed_files metadata is never populated from the GitHub webhook payload.

The code at line 152 reads ctx.Metadata["changed_files"] expecting a list of modified file paths, but this data is never extracted from the webhook event. The enrichIssueFromGitHubEvent and populateIssuePayload functions parse PR payloads but do not extract the files array. Since ListPullRequestFiles is never called before the command handler runs, and no other step populates this metadata, the type assertion will always fail and DocSync will silently never trigger.

To fix this, either:

  1. Extract file names from the webhook's files array during payload parsing and store in ctx.Metadata["changed_files"], or
  2. Call ListPullRequestFiles in gatekeeper or a dedicated early step to fetch PR files and populate the metadata.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@internal/steps/command_handler.go` around lines 146 - 159, The DocSync
trigger never sees changed files because ctx.Metadata["changed_files"] is never
populated; update the payload enrichment so pull-request file names are
extracted and stored, or ensure ListPullRequestFiles is invoked early to set
ctx.Metadata["changed_files"] before command handling. Specifically, modify
enrichIssueFromGitHubEvent or populateIssuePayload to parse the webhook PR
payload's files array (or call ListPullRequestFiles in the
gatekeeper/initialization step) and populate ctx.Metadata["changed_files"] with
[]string so matchesDocSyncPaths and handleDocSyncTrigger can run as intended.

@Kavirubc Kavirubc merged commit 8cab728 into main Mar 15, 2026
8 checks passed
@Kavirubc Kavirubc deleted the feat/claude-code-extended-features branch March 15, 2026 15:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ai enhancement New feature or request feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: Claude Code extended features — Issue Implementation, Doc Sync, Security Review, Checklists, Maintenance

2 participants