Skip to content

Fix pnpm module resolution and web test compilation #13

Fix pnpm module resolution and web test compilation

Fix pnpm module resolution and web test compilation #13

name: Issue Assessment
on:
issues:
types: [labeled]
jobs:
# Comment when need-more-info label is manually added
need-more-info:
if: github.event.label.name == 'need-more-info'
runs-on: ubuntu-latest
permissions:
issues: write
steps:
- name: Add comment
uses: actions/github-script@v7
with:
script: |
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: `## Additional Information Needed
This issue is missing information we need to investigate the problem.

Check failure on line 25 in .github/workflows/issue-assessment.yaml

View workflow run for this annotation

GitHub Actions / .github/workflows/issue-assessment.yaml

Invalid workflow file

You have an error in your yaml syntax on line 25
### Please provide:
- [ ] **Reproduction repository** — A public GitHub repo that demonstrates the issue
- [ ] **Prettier extension logs** — Click "Prettier" in the status bar and copy the output
- [ ] **Steps to reproduce** — Clear steps we can follow to see the issue
### Why this matters
Most issues are specific to your project's configuration. Without a reproduction, we usually cannot diagnose the problem.
### Resources
- [Creating a minimal reproduction](https://github.com/prettier/prettier-vscode/blob/main/docs/troubleshooting.md)
- [Writing a good issue](https://github.com/prettier/prettier-vscode/blob/main/docs/writing-an-issue.md)
> **Note:** Issues without the requested information may be closed after 7 days.`
});
triage:
if: github.event.label.name == 'triage-pending'
runs-on: ubuntu-latest
permissions:
issues: write
models: read
contents: read
outputs:
triage_labels: ${{ steps.triage.outputs.ai_assessments }}
steps:
- name: Checkout repository
uses: actions/checkout@v6
- name: Run Issue Triage
id: triage
uses: github/ai-assessment-comment-labeler@main
with:
token: ${{ secrets.GITHUB_TOKEN }}
issue_number: ${{ github.event.issue.number }}
issue_body: ${{ github.event.issue.body }}
ai_review_label: "triage-pending"
prompts_directory: "./.github/prompts"
labels_to_prompts_mapping: "triage-pending,issue-triage.prompt.yml"
- name: Remove pending label
uses: actions/github-script@v7
with:
script: |
await github.rest.issues.removeLabel({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
name: 'triage-pending'
}).catch(() => {});
post-triage:
runs-on: ubuntu-latest
needs: triage
if: always() && needs.triage.result == 'success'
permissions:
issues: write
steps:
- name: Process triage results and post comments
uses: actions/github-script@v7
env:
TRIAGE_OUTPUT: ${{ needs.triage.outputs.triage_labels }}
with:
script: |
const issueNumber = context.issue.number;
const triageOutput = process.env.TRIAGE_OUTPUT;
let triageAssessments = [];
try {
triageAssessments = JSON.parse(triageOutput || '[]');
} catch (e) {
console.log('Could not parse triage output:', e);
}
const triageLabel = triageAssessments[0]?.assessmentLabel || '';
console.log('Triage assessment label:', triageLabel);
const responses = {
'ai:issue-triage:needs-reproduction': {
addLabel: 'need-more-info',
comment: `## Reproduction Repository Needed
Thanks for the report! To investigate this issue, we need more information.
### Please provide:
1. **A GitHub repository** that reproduces the issue
2. **Step-by-step instructions** to reproduce the problem
3. **Prettier extension logs** — Click "Prettier" in the status bar and copy the output
### Why this matters
Most issues depend on specific project configurations. A reproduction repository lets us see exactly what you're experiencing.
### Resources
- [Creating a minimal reproduction](https://github.com/prettier/prettier-vscode/blob/main/docs/troubleshooting.md)
- [Writing a good issue](https://github.com/prettier/prettier-vscode/blob/main/docs/writing-an-issue.md)
> **Note:** Issues without reproduction info may be closed after 7 days.`
},
'ai:issue-triage:prettier-core': {
addLabel: 'prettier-core',
comment: `## This Looks Like a Prettier Core Issue
Thanks for the report! This issue appears to be about **how Prettier formats code**, not about the VS Code extension.
### Understanding the difference
| Prettier Core | VS Code Extension |
|--------------|-------------------|
| Decides *how* code is formatted | Integrates Prettier into VS Code |
| Formatting rules and output | Editor integration, settings UI |
| [prettier/prettier](https://github.com/prettier/prettier) | [prettier/prettier-vscode](https://github.com/prettier/prettier-vscode) |
### To confirm this is a Prettier Core issue
Run in your terminal:
\`\`\`bash
npx prettier --write yourfile.js
\`\`\`
If you see the same formatting behavior, it's a Prettier Core issue.
### Next steps
1. Check the [Prettier Playground](https://prettier.io/playground/) to test formatting
2. Search [existing Prettier issues](https://github.com/prettier/prettier/issues)
3. Open an issue at **[prettier/prettier](https://github.com/prettier/prettier/issues/new)**
### If this IS an extension issue
If the CLI formats differently than the extension, please reply with:
- Output from \`npx prettier --version\`
- Prettier extension logs
- Example showing the difference`
},
'ai:issue-triage:performance-info-needed': {
addLabel: 'need-more-info',
comment: `## Performance Information Needed
Thanks for reporting this performance issue! To investigate, we need additional details.
### Please provide:
| Information | How to get it |
|------------|---------------|
| Prettier version | Check the Prettier output panel |
| File size | Size of slow-to-format files |
| File types affected | Which languages/extensions |
| Prettier plugins | List any plugins you're using |
| Debug logs | Enable with \`"prettier.enableDebugLogs": true\` |
### Quick test
Compare with the CLI:
\`\`\`bash
time npx prettier --write yourfile.js
\`\`\`
If the CLI is also slow, the issue is with Prettier Core, not this extension.
### Optional: VS Code performance profile
1. Open Command Palette → **Developer: Start Performance Profile**
2. Format a document
3. Stop the profile and attach it here
> **Note:** Issues without the requested information may be closed after 7 days.`
},
'ai:issue-triage:incomplete-template': {
addLabel: 'need-more-info',
comment: `## Issue Template Incomplete
Thanks for opening this issue! Some required information is missing.
### Please edit your issue to include:
- [ ] **Summary** — Brief description of the problem
- [ ] **Reproduction repository** — Public GitHub repo demonstrating the issue
- [ ] **Steps to reproduce** — Clear steps to see the problem
- [ ] **Expected vs actual result** — What should happen vs what happens
- [ ] **Environment info:**
- VS Code version (\`Help → About → Copy\`)
- Prettier extension version
- Operating system
- [ ] **Prettier logs** — Click "Prettier" in status bar, copy output
### Resources
- [Writing a good issue](https://github.com/prettier/prettier-vscode/blob/main/docs/writing-an-issue.md)
- [Troubleshooting guide](https://github.com/prettier/prettier-vscode/blob/main/docs/troubleshooting.md)
> **Note:** Issues without the requested information may be closed after 7 days.`
},
'ai:issue-triage:support-question': {
comment: `## This Looks Like a Support Question
Thanks for reaching out! This appears to be a question about configuration or usage rather than a bug report.
### Get help here:
| Resource | Best for |
|----------|----------|
| [Stack Overflow](https://stackoverflow.com/questions/tagged/prettier-vscode) | Configuration questions |
| [Prettier Docs](https://prettier.io/docs/en/index.html) | Formatting options |
| [Extension Settings](https://github.com/prettier/prettier-vscode#settings) | VS Code settings |
| [Troubleshooting Guide](https://github.com/prettier/prettier-vscode/blob/main/docs/troubleshooting.md) | Common issues |
### If this is actually a bug
Please reopen with:
1. What you've already tried
2. A minimal reproduction repository
3. Prettier extension logs
We're happy to help with confirmed bugs!`
}
};
if (triageLabel && responses[triageLabel]) {
const response = responses[triageLabel];
if (response.comment) {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issueNumber,
body: response.comment
});
}
if (response.addLabel) {
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issueNumber,
labels: [response.addLabel]
});
}
}
# Duplicate detection
duplicate-search:
runs-on: ubuntu-latest
needs: triage
if: always() && needs.triage.result == 'success'
permissions:
issues: write
models: read
contents: read
steps:
- name: Checkout repository
uses: actions/checkout@v6
- name: Search for candidate issues
id: search
uses: actions/github-script@v7
with:
script: |
const issueTitle = context.payload.issue.title;
const issueBody = context.payload.issue.body || '';
const issueNumber = context.issue.number;
// Common words to filter out
const stopWords = new Set([
'the', 'a', 'an', 'is', 'are', 'was', 'were', 'be', 'been', 'being',
'have', 'has', 'had', 'do', 'does', 'did', 'will', 'would', 'could',
'should', 'may', 'might', 'must', 'can', 'need', 'to', 'of', 'in',
'for', 'on', 'with', 'at', 'by', 'from', 'as', 'into', 'through',
'during', 'before', 'after', 'then', 'once', 'here', 'there', 'when',
'where', 'why', 'how', 'all', 'each', 'few', 'more', 'most', 'other',
'some', 'such', 'no', 'nor', 'not', 'only', 'own', 'same', 'so',
'than', 'too', 'very', 'just', 'and', 'but', 'if', 'or', 'because',
'until', 'while', 'this', 'that', 'these', 'those', 'i', 'me', 'my',
'we', 'our', 'you', 'your', 'he', 'him', 'she', 'her', 'it', 'its',
'they', 'them', 'their', 'what', 'which', 'who', 'whom',
'prettier', 'vscode', 'extension', 'code', 'file', 'files', 'issue',
'bug', 'error', 'problem', 'help', 'please', 'work', 'working',
'works', 'doesnt', "doesn't", 'dont', "don't", 'cant', "can't",
'wont', "won't", 'using', 'use', 'get', 'getting', 'not', 'format',
'formatting', 'save', 'saving'
]);
const extractKeywords = (text) => {
return text
.toLowerCase()
.replace(/[^\w\s-]/g, ' ')
.split(/\s+/)
.filter(word => word.length > 2 && !stopWords.has(word));
};
const titleKeywords = extractKeywords(issueTitle);
console.log('Keywords:', titleKeywords);
if (titleKeywords.length === 0) {
console.log('No keywords, skipping');
core.setOutput('candidates', '[]');
core.setOutput('has_candidates', 'false');
return;
}
const searchKeywords = titleKeywords.slice(0, 4).join(' ');
const query = `repo:${context.repo.owner}/${context.repo.repo} is:issue ${searchKeywords}`;
let candidates = [];
try {
const result = await github.rest.search.issuesAndPullRequests({
q: query,
sort: 'updated',
order: 'desc',
per_page: 10
});
for (const issue of result.data.items) {
if (issue.number === issueNumber) continue;
candidates.push({
number: issue.number,
title: issue.title,
body: (issue.body || '').substring(0, 500),
state: issue.state,
url: issue.html_url
});
}
} catch (e) {
console.log('Search error:', e.message);
}
candidates = candidates.slice(0, 8);
console.log(`Found ${candidates.length} candidates`);
// Build comparison text for AI
const newIssue = `## NEW ISSUE #${issueNumber}
Title: ${issueTitle}
Body: ${issueBody.substring(0, 1000)}`;
let candidateText = '';
for (const c of candidates) {
candidateText += `\n\n## CANDIDATE ISSUE #${c.number} (${c.state})
Title: ${c.title}
Body: ${c.body}`;
}
const comparisonInput = newIssue + '\n\n---\n\nCANDIDATE ISSUES TO COMPARE:' + candidateText;
core.setOutput('candidates', JSON.stringify(candidates));
core.setOutput('has_candidates', candidates.length > 0 ? 'true' : 'false');
core.setOutput('comparison_input', comparisonInput);
- name: Duplicate Analysis
id: analysis
if: steps.search.outputs.has_candidates == 'true'
uses: github/ai-assessment-comment-labeler@main
with:
token: ${{ secrets.GITHUB_TOKEN }}
issue_number: ${{ github.event.issue.number }}
issue_body: ${{ steps.search.outputs.comparison_input }}
ai_review_label: "triage-pending"
prompts_directory: "./.github/prompts"
labels_to_prompts_mapping: "triage-pending,duplicate-comparison.prompt.yml"
suppress_comments: true
suppress_labels: true
- name: Post duplicate analysis results
if: steps.search.outputs.has_candidates == 'true'
uses: actions/github-script@v7
env:
AI_OUTPUT: ${{ steps.analysis.outputs.ai_assessments }}
CANDIDATES: ${{ steps.search.outputs.candidates }}
with:
script: |
const issueNumber = context.issue.number;
const aiOutput = process.env.AI_OUTPUT;
const candidatesJson = process.env.CANDIDATES;
let candidates = [];
try {
candidates = JSON.parse(candidatesJson || '[]');
} catch (e) {
console.log('Could not parse candidates');
return;
}
if (candidates.length === 0) {
console.log('No candidates to analyze');
return;
}
// Try to parse AI response
let aiAssessments = [];
let analysis = null;
try {
aiAssessments = JSON.parse(aiOutput || '[]');
const response = aiAssessments[0]?.response || '';
console.log('AI Response:', response);
// Try to extract JSON from the response
const jsonMatch = response.match(/\{[\s\S]*\}/);
if (jsonMatch) {
analysis = JSON.parse(jsonMatch[0]);
}
} catch (e) {
console.log('Could not parse AI analysis:', e.message);
}
// Build comment based on AI analysis
let comment = '';
let hasDuplicates = false;
let hasRelated = false;
if (analysis && (analysis.duplicates?.length > 0 || analysis.related?.length > 0)) {
// AI found duplicates or related issues
if (analysis.duplicates?.length > 0) {
hasDuplicates = true;
comment += `### Likely Duplicate Issues Found\n\n`;
comment += `This issue appears to be a duplicate of:\n\n`;
comment += `| Issue | Title | Confidence | Reason |\n`;
comment += `|-------|-------|------------|--------|\n`;
for (const dup of analysis.duplicates) {
const candidate = candidates.find(c => c.number === dup.number);
if (candidate) {
const title = candidate.title.replace(/\|/g, '\\|').substring(0, 40) + (candidate.title.length > 40 ? '...' : '');
const status = candidate.state === 'open' ? '🟢' : '🔴';
comment += `| ${status} #${dup.number} | ${title} | ${dup.confidence} | ${dup.reason} |\n`;
}
}
comment += `\n**Please check these issues.** If your issue is indeed a duplicate, close this issue and add your information to the existing one instead.\n\n`;
}
if (analysis.related?.length > 0) {
hasRelated = true;
comment += `### Possibly Related Issues\n\n`;
comment += `| Issue | Title | Reason |\n`;
comment += `|-------|-------|--------|\n`;
for (const rel of analysis.related) {
const candidate = candidates.find(c => c.number === rel.number);
if (candidate) {
const title = candidate.title.replace(/\|/g, '\\|').substring(0, 50) + (candidate.title.length > 50 ? '...' : '');
const status = candidate.state === 'open' ? '🟢' : '🔴';
comment += `| ${status} #${rel.number} | ${title} | ${rel.reason} |\n`;
}
}
comment += `\nThese issues might provide useful context or workarounds.\n\n`;
}
} else {
// Fallback: just show candidate issues if AI analysis failed
console.log('AI analysis unavailable, showing keyword matches');
comment = `### Potentially Related Issues\n\n`;
comment += `I found some existing issues that might be related based on keywords:\n\n`;
comment += `| Issue | Title | Status |\n`;
comment += `|-------|-------|--------|\n`;
for (const c of candidates.slice(0, 5)) {
const title = c.title.replace(/\|/g, '\\|').substring(0, 50) + (c.title.length > 50 ? '...' : '');
const status = c.state === 'open' ? '🟢 Open' : '🔴 Closed';
comment += `| #${c.number} | ${title} | ${status} |\n`;
}
comment += `\nPlease check if any of these address your issue.\n\n`;
}
comment += `---\n<sub>This analysis was generated automatically to help identify duplicate issues.</sub>`;
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issueNumber,
body: comment
});