Micro-PR 3: Issue Triage MVP - AI-Powered Issue Management#54
Micro-PR 3: Issue Triage MVP - AI-Powered Issue Management#54brendadeeznuts1111 wants to merge 3 commits intomainfrom
Conversation
…icts - Comment out CACHE binding in website worker - Comment out MCP_KV binding in MCP worker config - Allows Alchemy to properly clean up KV namespaces during deployment - Prevents Error 409 conflicts when deleting namespaces with active bindings This is a temporary fix until proper dependency management is implemented.
- Add AI-powered GitHub issue triage with keyword-based analysis - Implement GitHub API client for issue fetching and labeling - Create CLI commands for triage and analysis operations - Add comprehensive unit tests and integration tests - Create detailed documentation and usage examples Issue Triage MVP provides intelligent auto-labeling of GitHub issues based on content analysis, with confidence scoring and dry-run capabilities. Supports audience detection, topic classification, impact assessment, and type categorization for effective issue management. Builds upon Micro-PR 1: Health Infrastructure and Micro-PR 2: Grammar Parser. Part of RFC-006 AI Orchestration implementation sequence. Closes micro-PR 3 for RFC-006 AI Orchestration implementation.
WalkthroughThis pull request introduces GitHub issue management templates, comprehensive label definitions, a release checklist, documentation for an AI-powered issue triage system, and a new CLI tool ( Changes
Sequence DiagramsequenceDiagram
participant User
participant CLI as tgk CLI
participant GitHubClient
participant GitHubAPI
participant Analysis
User->>CLI: tgk-triage issue triage <issue-number>
CLI->>GitHubClient: Initialize with token
CLI->>GitHubClient: getIssue(issueNumber)
GitHubClient->>GitHubAPI: GET /repos/.../issues/<number>
GitHubAPI-->>GitHubClient: Issue data
GitHubClient-->>CLI: GitHubIssue object
CLI->>Analysis: performTriageAnalysis(issue)
Analysis->>Analysis: Analyze title & body<br/>Infer labels<br/>Calculate confidence
Analysis-->>CLI: TriageResult<br/>(labels, confidence, reasoning)
CLI->>CLI: displayTriageResults()
alt not dry-run and confidence >= threshold
CLI->>GitHubClient: addLabels(issueNumber, labels)
GitHubClient->>GitHubAPI: POST labels
GitHubAPI-->>GitHubClient: Success
end
GitHubClient-->>CLI: Complete
CLI-->>User: Display results
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes
Possibly related PRs
Suggested labels
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ 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 |
|
🎯 Council Review Requested @alice.smith @charlie.brown @diana.prince @frank.taylor Micro-PR 3: Issue Triage MVP is ready for your review! 🤖 What this implements:
🔗 Connection to Telegram: 📊 Test Results:
📚 Documentation:
Ready for review and merge! 🚀 Related to main PR #51 for micro-rfc-006 AI orchestration. |
There was a problem hiding this comment.
Actionable comments posted: 21
🧹 Nitpick comments (5)
.github/PULL_REQUEST_TEMPLATE.md (1)
128-131: Add language identifier to fenced code block.The Quick Labels code block should specify a language identifier for proper rendering. Consider using
textorbashas the identifier.Apply this diff:
## 🏷️ Quick Labels -``` +```text /label type/feature,component/worker,dept/infrastructure</blockquote></details> <details> <summary>.github/RELEASE_CHECKLIST.md (1)</summary><blockquote> `1-58`: **LGTM—Comprehensive release checklist with good operational practices.** The release checklist covers customer impact assessment, technical validation, and operational readiness. The rollback instructions provide a clear recovery path. Consider adding specific monitoring commands or dashboard links in the "Monitor for" section (line 56) to make the rollback process more actionable. For example: ```markdown 4. Monitor for: [key metrics to watch] - Error rate: https://dash.cloudflare.com/... - Latency p99: Grafana dashboard link - Customer reports: Telegram #incidents.github/ISSUE_TEMPLATE/customer_issue.yml (1)
1-26: LGTM—Customer issue template aligns with the label taxonomy.The template provides structured inputs for customer group, impact level, and thread URL, which align with the expanded label definitions in
.github/labels.yml.Consider marking critical fields as required to ensure complete issue reports:
- type: dropdown id: group attributes: label: "Customer group" options: - group-alpha - group-beta - enterprise - internal + validations: + required: true - type: dropdown id: impact attributes: label: "Impact level" options: - critical - high - low + validations: + required: truetgk/commands/issue-triage.ts (1)
72-75: Use distinct name in analyze action too.Mirror the rename for consistency.
- const issue = await client.getIssue(parseInt(issueNumber)); - const analysis = await performTriageAnalysis(issue); + const ghIssue = await client.getIssue(Number.parseInt(issueNumber, 10)); + const analysis = await performTriageAnalysis(ghIssue);tgk/commands/github-client.ts (1)
27-29: Strengthen the type guard for label mapping.The current type guard on line 28 assumes that if
labelis not a string, thenlabel.nameexists. However, if the label object lacks anameproperty, this would assignundefinedto the name field.Apply this diff to add a fallback:
- labels: response.data.labels.map(label => - typeof label === 'string' ? { name: label } : { name: label.name } - ) + labels: response.data.labels.map(label => + typeof label === 'string' ? { name: label } : { name: label.name || '' } + )
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
tgk/package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (16)
.github/ISSUE_TEMPLATE/customer_issue.yml(1 hunks).github/ISSUE_TEMPLATE/micro_rfc.yml(1 hunks).github/PULL_REQUEST_TEMPLATE.md(2 hunks).github/RELEASE_CHECKLIST.md(1 hunks).github/labels.yml(1 hunks)alchemy.run.ts(2 hunks)docs/issue-triage-mvp.md(1 hunks)rfcs/micro-rfc-006.md(1 hunks)tgk/cli.ts(1 hunks)tgk/commands/__tests__/issue-triage.test.ts(1 hunks)tgk/commands/github-client.ts(1 hunks)tgk/commands/grammar.ts(1 hunks)tgk/commands/issue-triage.ts(1 hunks)tgk/package.json(1 hunks)tgk/test-triage.sh(1 hunks)tgk/tsconfig.json(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (3)
tgk/commands/github-client.ts (1)
tgk/commands/issue-triage.ts (1)
GitHubIssue(182-189)
tgk/commands/issue-triage.ts (1)
tgk/commands/github-client.ts (2)
GitHubTriageClient(3-55)GitHubIssue(57-64)
tgk/cli.ts (2)
tgk/commands/issue-triage.ts (1)
createIssueTriageCommands(4-78)tgk/commands/grammar.ts (1)
createGrammarCommands(3-23)
🪛 Biome (2.1.2)
tgk/commands/issue-triage.ts
[error] 183-184: Shouldn't redeclare 'GitHubIssue'. Consider to delete it or rename it.
'GitHubIssue' is defined here:
(lint/suspicious/noRedeclare)
🪛 GitHub Actions: PR Validation & Quality Gates
tgk/commands/grammar.ts
[error] 1-1: Code formatting issues detected by oxfmt. Run 'bun run format' to fix.
tgk/commands/__tests__/issue-triage.test.ts
[error] 1-1: Code formatting issues detected by oxfmt. Run 'bun run format' to fix.
tgk/commands/github-client.ts
[error] 1-1: Code formatting issues detected by oxfmt. Run 'bun run format' to fix.
tgk/commands/issue-triage.ts
[error] 1-1: Code formatting issues detected by oxfmt. Run 'bun run format' to fix.
tgk/cli.ts
[error] 1-1: Code formatting issues detected by oxfmt. Run 'bun run format' to fix.
alchemy.run.ts
[error] 39-39: Command 'bun ./alchemy.run.ts --stage pr-test' failed with exit code 1. Alchemy configuration has errors (Missing ALCHEMY_STATE_TOKEN).
🪛 LanguageTool
rfcs/micro-rfc-006.md
[uncategorized] ~6-~6: The official name of this software platform is spelled with a capital “H”.
Context: ...(v5.0.0) Files tgk/commands/* + .github/workflows/* + docs/rfcs/* Author...
(GITHUB)
[uncategorized] ~63-~63: The official name of this software platform is spelled with a capital “H”.
Context: ...tor(≤80 LOC) - [ ] land workflows.github/workflows/issue-triage.yml, release.y...
(GITHUB)
docs/issue-triage-mvp.md
[grammar] ~53-~53: Use a hyphen to join words.
Context: ...ate attention - impact/high - High priority issues with significant impact ...
(QB_NEW_EN_HYPHEN)
[grammar] ~54-~54: Use a hyphen to join words.
Context: ...nificant impact - impact/low - Low priority issues with minimal impact ###...
(QB_NEW_EN_HYPHEN)
🪛 markdownlint-cli2 (0.18.1)
rfcs/micro-rfc-006.md
37-37: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
docs/issue-triage-mvp.md
178-178: Emphasis used instead of a heading
(MD036, no-emphasis-as-heading)
182-182: Emphasis used instead of a heading
(MD036, no-emphasis-as-heading)
186-186: Emphasis used instead of a heading
(MD036, no-emphasis-as-heading)
191-191: Emphasis used instead of a heading
(MD036, no-emphasis-as-heading)
.github/PULL_REQUEST_TEMPLATE.md
129-129: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🪛 Shellcheck (0.11.0)
tgk/test-triage.sh
[warning] 13-13: Use 'cd ... || exit' or 'cd ... || return' in case cd fails.
(SC2164)
🪛 YAMLlint (1.37.1)
.github/ISSUE_TEMPLATE/micro_rfc.yml
[error] 11-11: syntax error: mapping values are not allowed here
(syntax)
🔇 Additional comments (9)
alchemy.run.ts (2)
234-237: LGTM—MCP worker bindings consistently disabled.The CACHE and MCP_KV bindings are appropriately commented out in the MCP worker configuration, maintaining consistency with the website worker changes.
1-41: I need to gather more context about whether the ALCHEMY_STATE_TOKEN is actually a code requirement or an environmental configuration issue.The web search didn't reveal any documentation about "ALCHEMY_STATE_TOKEN." Let me search the codebase for CI configuration and deployment documentation:
The code in
alchemy.run.tsdoes not reference or requireALCHEMY_STATE_TOKEN. TheCloudflareStateStoreis correctly instantiated with only thescopeparameter (line 39), which aligns with Alchemy's documented state store patterns. The error message "Missing ALCHEMY_STATE_TOKEN" is neither documented in official Alchemy or Cloudflare documentation, nor present in the codebase. This appears to be an environmental or deployment configuration issue rather than a code defect in this file. If the CI pipeline is failing, verify that your GitHub Actions secrets or deployment configuration is properly set up, but this is not a code-level concern foralchemy.run.ts.Likely an incorrect or invalid review comment.
tgk/tsconfig.json (1)
1-17: LGTM—TypeScript configuration is appropriate for a modern Node.js CLI.The configuration uses strict mode, ES2022 target, and bundler module resolution, which are appropriate choices for the tgk CLI tool. The settings align with the package.json requirements.
tgk/cli.ts (1)
1-1: Formatting gate failing (oxfmt).Run: bun run format
tgk/commands/grammar.ts (1)
1-1: Formatting gate failing (oxfmt).Run: bun run format
tgk/commands/__tests__/issue-triage.test.ts (1)
1-1: Formatting gate failing (oxfmt).Run: bun run format
tgk/commands/issue-triage.ts (1)
1-1: Formatting gate failing (oxfmt).Run: bun run format
tgk/commands/github-client.ts (2)
8-12: LGTM!The constructor correctly initializes the Octokit client with authentication and sets owner/repo defaults suitable for the MVP.
44-54: LGTM!The method correctly creates an issue and returns its number. The default empty array for labels is appropriate.
| - type: textarea | ||
| label: "40-line diff" | ||
| description: "Paste the exact patch" |
There was a problem hiding this comment.
Critical: YAML syntax error will break the template.
Line 11 is missing the attributes: key. The second textarea should have the same structure as the first one.
Apply this diff to fix the syntax error:
- type: textarea
+ attributes:
label: "40-line diff"
description: "Paste the exact patch"📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| - type: textarea | |
| label: "40-line diff" | |
| description: "Paste the exact patch" | |
| - type: textarea | |
| attributes: | |
| label: "40-line diff" | |
| description: "Paste the exact patch" |
🧰 Tools
🪛 YAMLlint (1.37.1)
[error] 11-11: syntax error: mapping values are not allowed here
(syntax)
🤖 Prompt for AI Agents
In .github/ISSUE_TEMPLATE/micro_rfc.yml around lines 10 to 12, the second
textarea block is missing the required top-level attributes: key which breaks
YAML; add an attributes: key for that textarea so it mirrors the first
textarea's structure (i.e., place attributes: directly above the type: textarea
line and include the same nested label and description entries), ensuring proper
indentation and consistent keys to fix the syntax error.
| # CUSTOMER GROUP | ||
| - name: "customer/group-alpha" | ||
| color: "0366d6" | ||
| description: "Alpha testers / early adopters" | ||
| - name: "customer/group-beta" | ||
| color: "0366d6" | ||
| description: "Beta users" | ||
| - name: "customer/enterprise" | ||
| color: "0366d6" | ||
| description: "Paid enterprise accounts" | ||
| - name: "customer/internal" | ||
| color: "0366d6" | ||
| description: "Dog-food / internal usage" | ||
|
|
There was a problem hiding this comment.
🧩 Analysis chain
Add AUDIENCE labels to match triage output (“customer”, “internal”).
Triage adds plain “customer” and “internal” but the taxonomy only has customer/* and no plain audience labels. Add explicit labels or adjust code.
+# AUDIENCE
+- name: "customer"
+ color: "1d76db"
+ description: "Customer-facing issues"
+- name: "internal"
+ color: "cfd3d7"
+ description: "Internal team issues"To verify all label names used by code/tests exist in labels.yml, run:
🏁 Script executed:
#!/bin/bash
# Compare labels used in code vs defined labels
echo "Labels used by code/tests:"
rg -nP --glob '!**/node_modules/**' "(topic\/[a-z\-]+|impact\/(critical|high|low)|type\/(bug|feature|question)|\bcustomer\b|\binternal\b)" -o | awk '{print $NF}' | sed 's/["'\'',()]//g' | sort -u
echo
echo "Labels defined in .github/labels.yml:"
rg -nP '(?<=name:\s*")[^"]+' .github/labels.yml | awk -F: '{print $2}' | xargs -I{} echo {}
echo
echo "Missing in labels.yml:"
comm -23 <(rg -nP --glob '!**/node_modules/**' "(topic\/[a-z\-]+|impact\/(critical|high|low)|type\/(bug|feature|question)|\bcustomer\b|\binternal\b)" -o | awk '{print $NF}' | sed 's/["'\'',()]//g' | sort -u) <(rg -nP '(?<=name:\s*")[^"]+' .github/labels.yml | awk -F: '{print $2}' | sort -u)Length of output: 3298
---
🏁 Script executed:
```shell
#!/bin/bash
# Fix: Use simpler pattern to extract labels from labels.yml
echo "Labels defined in .github/labels.yml:"
rg -nP '^- name: "[^"]+"' .github/labels.yml -o | sed 's/.*name: "\([^"]*\)".*/\1/' | sort -u
echo
echo "Check if plain 'customer' and 'internal' labels exist:"
rg -nP '^- name: "(customer|internal)"$' .github/labels.yml
echo
echo "Labels used in code (plain names only):"
rg -nP --glob '!**/node_modules/**' '\b(customer|internal)\b' -o --type-list | grep -E '(issue-triage|customer|internal)' | head -20
Length of output: 642
🏁 Script executed:
#!/bin/bash
# Extract labels from labels.yml - simpler approach
echo "=== Labels defined in .github/labels.yml ==="
grep -E '^\s*- name:' .github/labels.yml | sed 's/.*name: "\([^"]*\)".*/\1/' | sort -u
echo
echo "=== Check if plain 'customer' or 'internal' labels exist ==="
grep -E '^\s*- name: "(customer|internal)"' .github/labels.yml && echo "Found" || echo "Not found"
echo
echo "=== All label names in labels.yml for reference ==="
grep -E '^\s*- name:' .github/labels.yml | wc -l
echo "labels total"Length of output: 790
Add plain "customer" and "internal" labels to .github/labels.yml
Verification confirms that the code uses plain customer and internal labels (found in tgk/commands/issue-triage.ts and test files), but these labels are not defined in .github/labels.yml. Only namespaced variants like customer/enterprise, customer/group-alpha, customer/group-beta, and customer/internal are currently defined. The suggested addition is required to match the triage output.
+# AUDIENCE
+- name: "customer"
+ color: "1d76db"
+ description: "Customer-facing issues"
+- name: "internal"
+ color: "cfd3d7"
+ description: "Internal team issues"Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In .github/labels.yml around lines 85 to 98 the file defines namespaced customer
labels but is missing the plain "customer" and "internal" labels referenced by
the triage code; add two new label entries: one with name "customer", color
"0366d6", and a brief description like "Customer-related issues", and one with
name "internal", color "0366d6", and a brief description like "Internal issues /
dog-fooding", placing them near the existing CUSTOMER GROUP section so the
triage output maps to defined labels.
| # CUSTOMER TOPIC | ||
| - name: "topic/telegram-group" | ||
| color: "1d76db" | ||
| description: "Telegram super-group feature" | ||
| - name: "topic/forum-topic" | ||
| color: "1d76db" | ||
| description: "Forum topic / thread" | ||
| - name: "topic/state-pinning" | ||
| color: "1d76db" | ||
| description: "Pinned message state" | ||
| - name: "topic/race-condition" | ||
| color: "1d76db" | ||
| description: "Concurrent update issues" | ||
|
|
There was a problem hiding this comment.
Align labels with code: add missing topics used by triage.
Code uses topic/telegram-integration and topic/deployment; tests expect topic/telegram-integration. Add them to avoid mismatches and surprise label creation.
# CUSTOMER TOPIC
- name: "topic/telegram-group"
color: "1d76db"
description: "Telegram super-group feature"
- name: "topic/forum-topic"
color: "1d76db"
description: "Forum topic / thread"
- name: "topic/state-pinning"
color: "1d76db"
description: "Pinned message state"
- name: "topic/race-condition"
color: "1d76db"
description: "Concurrent update issues"
+ - name: "topic/telegram-integration"
+ color: "1d76db"
+ description: "Telegram integration issues"
+ - name: "topic/deployment"
+ color: "1d76db"
+ description: "Deployment/worker issues"Also applies to: 113-123
🤖 Prompt for AI Agents
In .github/labels.yml around lines 99-112 (and also apply the same changes to
113-123), the file is missing labels referenced by code/tests
(topic/telegram-integration and topic/deployment); add entries for "name:
\"topic/telegram-integration\"" and "name: \"topic/deployment\"" with the
existing project color (e.g., "1d76db") and appropriate descriptions ("Telegram
integration" and "Deployment topic") so labels align with code and tests and
prevent on-the-fly label creation.
| // Temporarily disable KV bindings to allow cleanup during deployment | ||
| // CACHE: resources.cache, |
There was a problem hiding this comment.
🧩 Analysis chain
Verify that removing the CACHE binding doesn't break dependent code.
The CACHE KV binding has been disabled. Ensure that no code in src/backend/server.ts or related modules attempts to access env.CACHE, as this will cause runtime errors.
Run the following script to check for CACHE usage:
🏁 Script executed:
#!/bin/bash
# Search for CACHE binding usage in the codebase
rg -nP --type=ts -C3 '\benv\.CACHE\b|\bCACHE\s*[:\.]' -g '!alchemy.run.ts'Length of output: 2336
Remove CACHE binding disable or handle gracefully in dependent code.
The search confirms active CACHE usage that will cause runtime errors:
src/mcp/tools.ts:433— callsenv.CACHE.list()src/backend/server.ts:121, 128— callsenv.CACHE.get()andenv.CACHE.put()
Either re-enable the CACHE binding in alchemy.run.ts:159-160 or remove these API endpoints and tool methods that depend on it.
| - **`impact/critical`** - Critical/urgent issues requiring immediate attention | ||
| - **`impact/high`** - High priority issues with significant impact | ||
| - **`impact/low`** - Low priority issues with minimal impact | ||
|
|
There was a problem hiding this comment.
Hyphenate compound modifiers.
Use “High-priority” and “Low-priority.”
-**`impact/high`** - High priority issues with significant impact
+**`impact/high`** - High-priority issues with significant impact
-**`impact/low`** - Low priority issues with minimal impact
+**`impact/low`** - Low-priority issues with minimal impact📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| - **`impact/critical`** - Critical/urgent issues requiring immediate attention | |
| - **`impact/high`** - High priority issues with significant impact | |
| - **`impact/low`** - Low priority issues with minimal impact | |
| - **`impact/critical`** - Critical/urgent issues requiring immediate attention | |
| - **`impact/high`** - High-priority issues with significant impact | |
| - **`impact/low`** - Low-priority issues with minimal impact | |
🧰 Tools
🪛 LanguageTool
[grammar] ~53-~53: Use a hyphen to join words.
Context: ...ate attention - impact/high - High priority issues with significant impact ...
(QB_NEW_EN_HYPHEN)
[grammar] ~54-~54: Use a hyphen to join words.
Context: ...nificant impact - impact/low - Low priority issues with minimal impact ###...
(QB_NEW_EN_HYPHEN)
🤖 Prompt for AI Agents
In docs/issue-triage-mvp.md around lines 52 to 55, the compound modifiers "High
priority" and "Low priority" should be hyphenated; update the three bullet lines
so the labels read "impact/critical" - Critical/urgent issues requiring
immediate attention, "impact/high" - High-priority issues with significant
impact, and "impact/low" - Low-priority issues with minimal impact, ensuring
only the displayed descriptive text is changed to use hyphenation while
preserving the label keys.
| // Simple but effective triage logic | ||
| async function performTriageAnalysis(issue: GitHubIssue): Promise<TriageResult> { | ||
| const labels: string[] = []; | ||
| let confidence = 0.5; // Base confidence | ||
| const reasoning: string[] = []; | ||
|
|
||
| // 1. Determine audience (customer vs internal) | ||
| if (issue.repository?.full_name?.includes('customer') || issue.body?.includes('customer')) { | ||
| labels.push('customer'); | ||
| confidence += 0.1; | ||
| reasoning.push('Repository or content mentions customer context'); | ||
| } else { | ||
| labels.push('internal'); | ||
| confidence += 0.1; | ||
| reasoning.push('Internal repository and no customer mentions'); | ||
| } | ||
|
|
||
| // 2. Determine topic from title/body analysis | ||
| const titleLower = issue.title.toLowerCase(); | ||
| const bodyLower = issue.body?.toLowerCase() || ''; | ||
| const combinedText = `${titleLower} ${bodyLower}`; | ||
|
|
||
| // Technical topics | ||
| if (combinedText.includes('race') || combinedText.includes('concurrent') || combinedText.includes('pin')) { | ||
| labels.push('topic/state-pinning'); | ||
| confidence += 0.2; | ||
| reasoning.push('Content suggests state/concurrency issues'); | ||
| } | ||
|
|
||
| if (combinedText.includes('telegram') || combinedText.includes('message')) { | ||
| labels.push('topic/telegram-integration'); | ||
| confidence += 0.15; | ||
| reasoning.push('Telegram-related content detected'); | ||
| } | ||
|
|
||
| if (combinedText.includes('deploy') || combinedText.includes('worker')) { | ||
| labels.push('topic/deployment'); | ||
| confidence += 0.15; | ||
| reasoning.push('Deployment/worker-related content detected'); | ||
| } | ||
|
|
||
| // 3. Determine impact level | ||
| if (combinedText.includes('critical') || combinedText.includes('urgent') || combinedText.includes('breaking')) { | ||
| labels.push('impact/critical'); | ||
| confidence += 0.2; | ||
| reasoning.push('Critical/urgent language detected'); | ||
| } else if (combinedText.includes('important') || combinedText.includes('significant') || (issue.body?.length || 0) > 500) { | ||
| labels.push('impact/high'); | ||
| confidence += 0.15; | ||
| reasoning.push('Detailed description or important language detected'); | ||
| } else { | ||
| labels.push('impact/low'); | ||
| confidence += 0.1; | ||
| reasoning.push('Standard issue complexity'); | ||
| } | ||
|
|
||
| // 4. Determine type | ||
| if (combinedText.includes('bug') || combinedText.includes('error') || combinedText.includes('broken')) { | ||
| labels.push('type/bug'); | ||
| confidence += 0.1; | ||
| reasoning.push('Bug/error language detected'); | ||
| } else if (combinedText.includes('feature') || combinedText.includes('enhancement')) { | ||
| labels.push('type/feature'); | ||
| confidence += 0.1; | ||
| reasoning.push('Feature request language detected'); | ||
| } else { | ||
| labels.push('type/question'); | ||
| confidence += 0.05; | ||
| reasoning.push('General inquiry format'); | ||
| } | ||
|
|
||
| // Normalize confidence (cap at 0.95) | ||
| confidence = Math.min(confidence, 0.95); | ||
|
|
||
| return { | ||
| labels, | ||
| confidence, | ||
| reasoning: reasoning.join('; '), | ||
| timestamp: new Date().toISOString() | ||
| }; | ||
| } |
There was a problem hiding this comment.
Export performTriageAnalysis for tests and reuse.
Tests import performTriageAnalysis; function is not exported.
-async function performTriageAnalysis(issue: GitHubIssue): Promise<TriageResult> {
+export async function performTriageAnalysis(issue: GitHubIssue): Promise<TriageResult> {🤖 Prompt for AI Agents
In tgk/commands/issue-triage.ts around lines 80-160, the performTriageAnalysis
function is declared but not exported, causing test imports to fail; export the
function so it can be imported by tests and other modules—either add the export
keyword to the function declaration (export async function
performTriageAnalysis(...)) or add an explicit export at the bottom of the file
(export { performTriageAnalysis }); ensure any existing default export is
preserved or updated accordingly and that import paths in tests remain correct.
| // Types | ||
| export interface GitHubIssue { | ||
| number: number; | ||
| title: string; | ||
| body?: string; | ||
| user: { login: string }; | ||
| repository?: { full_name: string }; | ||
| labels: Array<{ name: string }>; | ||
| } |
There was a problem hiding this comment.
Remove duplicate GitHubIssue interface (source of Biome error).
The interface is defined in github-client.ts; re-export that one here.
-export interface GitHubIssue {
- number: number;
- title: string;
- body?: string;
- user: { login: string };
- repository?: { full_name: string };
- labels: Array<{ name: string }>;
-}
+// GitHubIssue is re-exported from './github-client'Committable suggestion skipped: line range outside the PR's diff.
🧰 Tools
🪛 Biome (2.1.2)
[error] 183-184: Shouldn't redeclare 'GitHubIssue'. Consider to delete it or rename it.
'GitHubIssue' is defined here:
(lint/suspicious/noRedeclare)
🤖 Prompt for AI Agents
In tgk/commands/issue-triage.ts around lines 181 to 189, remove the duplicate
GitHubIssue interface declaration and instead import and re-export the existing
interface from github-client.ts (or import it and use it directly) to avoid the
Biome conflict; update import statements at the top of the file to import {
GitHubIssue } from '../path/to/github-client' (use the correct relative path)
and delete the local interface block so the file references the shared type
only.
| "bin": { | ||
| "tgk-triage": "./cli.ts" | ||
| }, |
There was a problem hiding this comment.
🧩 Analysis chain
Verify that cli.ts has a proper shebang for executable usage.
The bin configuration points directly to ./cli.ts, which requires either a TypeScript runtime (tsx, ts-node) or a build step. Ensure cli.ts has the appropriate shebang line for execution.
Check if the CLI entry point is properly configured:
Expected shebang examples:
- For tsx:
#!/usr/bin/env tsx - For ts-node:
#!/usr/bin/env ts-node - For node (after build):
#!/usr/bin/env node
🏁 Script executed:
#!/bin/bash
# Check for shebang in cli.ts and verify executable setup
fd -t f 'cli.ts' tgk/ --exec head -n 5 {}Length of output: 89
I found the shebang in cli.ts, but need to verify a critical issue: the file is TypeScript (.ts), yet it has #!/usr/bin/env node. Node.js cannot directly execute TypeScript without transpilation. Let me check the build configuration and file permissions.
---
🏁 Script executed:
```shell
#!/bin/bash
# Check file permissions and build configuration
echo "=== cli.ts permissions ==="
ls -la tgk/cli.ts 2>/dev/null || echo "File not found"
echo -e "\n=== tsconfig.json ==="
cat tgk/tsconfig.json 2>/dev/null || echo "No tsconfig found"
echo -e "\n=== package.json build/scripts section ==="
cat tgk/package.json | grep -A 10 '"scripts"'
echo -e "\n=== Check for build output/dist ==="
ls -la tgk/dist/ 2>/dev/null || ls -la tgk/build/ 2>/dev/null || echo "No dist/build found"
Length of output: 841
File is not executable and shebang is incompatible with TypeScript source.
Multiple critical issues found:
- File permissions: cli.ts lacks executable bit (
-rw-r--r--should be-rwxr-xr-x) - Invalid shebang for TypeScript: Using
#!/usr/bin/env nodeon a .ts file fails—Node.js cannot execute TypeScript directly without a loader. Should be#!/usr/bin/env tsxor similar. - Undefined build-to-bin flow: The bin entry points to source .ts, but tsconfig.json doesn't specify an outDir. Either:
- Update bin to point to compiled output:
"tgk-triage": "./dist/cli.js"(after build) - Or use
#!/usr/bin/env tsxand install tsx as a dependency - Or configure Node.js loader support
- Update bin to point to compiled output:
Ensure the CLI is executable and the shebang matches your runtime (tsx, ts-node, or compiled Node.js).
🤖 Prompt for AI Agents
In tgk/package.json around lines 7 to 9, the bin entry points at a TypeScript
source file which is not executable and uses an incompatible runtime; make the
CLI runnable by either (A) switching the bin to the compiled JS output (e.g.
after a build set tsconfig.outDir and change the bin to ./dist/cli.js) and
ensure your build step emits that file, or (B) keep the .ts entry but add a
compatible shebang (#!/usr/bin/env tsx or ts-node) and add tsx/ts-node as a
dependency and an npm script to invoke it; additionally set the executable bit
on the CLI file (chmod +x cli.ts or chmod +x dist/cli.js) and update
package.json scripts to reflect the chosen build/run flow so npm can execute the
bin correctly.
| "scripts": { | ||
| "start": "node cli.ts", | ||
| "test": "jest", | ||
| "build": "tsc" |
There was a problem hiding this comment.
Update npm scripts to handle TypeScript execution correctly.
The start script runs node cli.ts, but Node.js cannot execute TypeScript directly. Either use a TypeScript runtime or compile first.
Apply this diff to fix the scripts:
"scripts": {
- "start": "node cli.ts",
+ "start": "tsx cli.ts",
"test": "jest",
- "build": "tsc"
+ "build": "tsc",
+ "prepack": "npm run build"
},And add tsx to devDependencies:
"devDependencies": {
"@types/node": "^20.0.0",
"typescript": "^5.0.0",
"jest": "^29.0.0",
"tsx": "^4.0.0"
}🤖 Prompt for AI Agents
In tgk/package.json around lines 10 to 13, the "start" script uses "node cli.ts"
which won't run TypeScript directly; update the scripts to run TypeScript via a
runtime (e.g., change "start" to use "tsx cli.ts" and keep "build": "tsc" and
"test": "jest"), and add the provided devDependencies block to package.json
(including "tsx": "^4.0.0", "typescript", "@types/node", and "jest") so the tsx
runtime and TypeScript tooling are available for development.
| # Check if GitHub token is available | ||
| if [ -z "$GITHUB_TOKEN" ]; then | ||
| echo "⚠️ GITHUB_TOKEN not set - running limited tests without API calls" | ||
| echo "" | ||
| fi | ||
|
|
||
| echo "1️⃣ Running unit tests..." | ||
| cd /Users/nolarose/alchmenyrun/tgk | ||
| npm test | ||
|
|
There was a problem hiding this comment.
Make script portable; guard cd; run TS properly.
- Avoid absolute paths and unguarded cd (SC2164).
- Add strict mode; run TS with tsx (or built JS) instead of raw node on .ts.
Apply:
#!/bin/bash
+set -euo pipefail
+
echo "🧪 Testing Issue Triage MVP"
===========================
# Check if GitHub token is available
if [ -z "$GITHUB_TOKEN" ]; then
echo "⚠️ GITHUB_TOKEN not set - running limited tests without API calls"
echo ""
fi
echo "1️⃣ Running unit tests..."
-cd /Users/nolarose/alchmenyrun/tgk
+cd "$(dirname "$0")" || exit 1
npm testAnd prefer TS runner or built JS:
- node cli.ts --help
+ npx tsx cli.ts --help(Repeat for other node cli.ts invocations), or run npm run build and node dist/cli.js ....
Committable suggestion skipped: line range outside the PR's diff.
🧰 Tools
🪛 Shellcheck (0.11.0)
[warning] 13-13: Use 'cd ... || exit' or 'cd ... || return' in case cd fails.
(SC2164)
🤖 Prompt for AI Agents
In tgk/test-triage.sh around lines 6 to 15, the script uses an absolute path,
does an unguarded cd (SC2164) and invokes tests in a way that may run raw .ts
with node; make the script portable by adding a strict shell header (e.g. set
-euo pipefail), check and guard the cd (ensure the directory exists before
changing into it, or use cd "$SCRIPT_DIR" && to stop on failure), replace the
hard-coded absolute path with a relative or computed path (e.g. derive project
root from the script location), and run TypeScript via a TS runner or built JS
(invoke tsx or run npm run build && node dist/cli.js or use npx tsx) instead of
calling node on .ts; apply the same pattern for other node cli.ts invocations in
the repo.
🤖 Micro-PR 3: Issue Triage MVP
Overview
Implements AI-powered GitHub issue triage with automatic labeling and confidence-based decision making.
✅ What's Implemented
🧪 Testing
📚 Documentation
Ready for merge - Immediate value for issue management workflow.
Related to Main PR
Part of micro-rfc-006 AI orchestration implementation.
Summary by CodeRabbit
New Features
Documentation
Chores