Conversation
- 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>
📝 WalkthroughWalkthroughAdds 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
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
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
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. Comment |
Simili Triage ReportNote Quality Score: 8.8/10 (Good) Classification
Quality Improvements
Similar Threads
Warning Possible Duplicate (Confidence: 98%) ⏳ 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 |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (5)
internal/steps/claude_code_issue_implement.go (1)
38-42: HandlewriteGitHubOutputerrors 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.Matcherrors (fromok, _ :=) are silently discarded. While this only occurs for malformed patterns (not runtime failures), logging would help users debug invalidwatch_pathsconfiguration.🔧 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: HandlewriteGitHubOutputerrors 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: HandlewriteGitHubOutputerrors consistently.The return values from
writeGitHubOutputare ignored here, but the function can fail when opening or writing to theGITHUB_OUTPUTfile. The existinghandleClaudeCodeTriggerinclaude_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: HandlewriteGitHubOutputerrors consistently.Same issue as
handleSecurityReviewTrigger— the error returns are ignored. Add warning logs for consistency withhandleClaudeCodeTrigger.♻️ 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
📒 Files selected for processing (9)
.github/workflows/triage.ymlDOCS/examples/single-repo/workflow.ymlaction.ymlinternal/core/config/config.gointernal/steps/claude_code_doc_sync.gointernal/steps/claude_code_issue_implement.gointernal/steps/claude_code_maintenance.gointernal/steps/claude_code_review.gointernal/steps/command_handler.go
|
@simili-bot Fix the coderabbit and LINT errors and add a commit to the PR |
|
Claude finished @Kavirubc's task in 1m 58s —— View job Fixed CodeRabbit and LINT ErrorsAll issues identified by CodeRabbit and the errcheck linter have been resolved. Tasks completed:
Changes made
Dead code fix — Glob pattern logging — |
… 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>
There was a problem hiding this comment.
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
📒 Files selected for processing (5)
internal/steps/claude_code_doc_sync.gointernal/steps/claude_code_issue_implement.gointernal/steps/claude_code_maintenance.gointernal/steps/claude_code_review.gointernal/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
|
@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 finished @Kavirubc's task in 5m 27s —— View job CodeRabbit Fixes — 3 Issues ResolvedAll 3 actionable issues from CodeRabbit's second review have been fixed in commit Changes madeFix 1 — Doublestar glob support (
Fix 2 — Match only the newly-added label ( On
Fix 3 — Guard Doc Sync when Doc Sync was triggering even when if cc.DocSync.Enabled != nil && *cc.DocSync.Enabled &&
len(cc.DocSync.WatchPaths) > 0 && len(cc.DocSync.DocPaths) > 0 {Files changed
|
…_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>
There was a problem hiding this comment.
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
📒 Files selected for processing (4)
cmd/simili/commands/process.gointernal/core/pipeline/pipeline.gointernal/steps/claude_code_doc_sync.gointernal/steps/command_handler.go
🚧 Files skipped from review as they are similar to previous changes (1)
- internal/steps/claude_code_doc_sync.go
| // 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) | ||
| } | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
🧩 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 -C3Repository: 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 -C2Repository: 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=goRepository: 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 -iRepository: 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 -80Repository: 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 -A3Repository: 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 -iRepository: 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 -150Repository: 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.goRepository: 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 -100Repository: 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 -A2Repository: similigh/simili-bot
Length of output: 6746
🏁 Script executed:
#!/bin/bash
echo "=== Read complete enrichIssueFromGitHubEvent function ==="
sed -n '343,450p' cmd/simili/commands/process.goRepository: 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:
- Extract file names from the webhook's
filesarray during payload parsing and store inctx.Metadata["changed_files"], or - Call
ListPullRequestFilesin 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.
Summary
Extends the Claude Code integration with 5 new features, all configurable via
.github/simili.yamlunderclaude_code:.Depends on: #106 (base
@simili-botmention 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 indoc_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
Files Changed
Go Code
internal/core/config/config.goClaudeCodeConfigstruct + 5 sub-configs, defaults, mergeinternal/steps/claude_code_issue_implement.gointernal/steps/claude_code_doc_sync.gointernal/steps/claude_code_review.gointernal/steps/claude_code_maintenance.gointernal/steps/command_handler.goAction & Workflow
action.ymlpromptandmodeoutputs.github/workflows/triage.ymlDOCS/examples/single-repo/workflow.ymlCommits (modular)
feat(config)— ClaudeCodeConfig structfeat(handlers)— Issue implementation handlerfeat(handlers)— Doc sync handlerfeat(handlers)— Security review + review checklist handlersfeat(handlers)— Scheduled maintenance handlerfeat(routing)— Command handler wiringfeat(workflow)— Action outputs + triage workflow + nil fixTesting
go build ./...✅go test ./...✅ (all packages)go vet ./...✅Checklist
Summary by CodeRabbit
New Features
Chores