Merge remote-tracking branch 'origin/main' into garrytan/resolver-factoring

# Conflicts:
#	CHANGELOG.md
#	investigate/SKILL.md
#	investigate/SKILL.md.tmpl
#	office-hours/SKILL.md
#	office-hours/SKILL.md.tmpl
#	ship/SKILL.md
#	ship/SKILL.md.tmpl
This commit is contained in:
Garry Tan
2026-03-29 21:21:46 -07:00
70 changed files with 898 additions and 367 deletions
+27
View File
@@ -1547,3 +1547,30 @@ describe('Test failure triage in ship skill', () => {
expect(content).toContain('In-branch test failures');
});
});
describe('sidebar agent (#584)', () => {
// #584 — Sidebar Write: sidebar-agent.ts allowedTools includes Write
test('sidebar-agent.ts allowedTools includes Write', () => {
const content = fs.readFileSync(path.join(ROOT, 'browse', 'src', 'sidebar-agent.ts'), 'utf-8');
// Find the allowedTools line in the askClaude function
const match = content.match(/--allowedTools['"]\s*,\s*['"]([^'"]+)['"]/);
expect(match).not.toBeNull();
expect(match![1]).toContain('Write');
});
// #584 — Server Write: server.ts allowedTools includes Write (DRY parity)
test('server.ts allowedTools includes Write', () => {
const content = fs.readFileSync(path.join(ROOT, 'browse', 'src', 'server.ts'), 'utf-8');
// Find the sidebar allowedTools in the headed-mode path
const match = content.match(/--allowedTools['"]\s*,\s*['"]([^'"]+)['"]/);
expect(match).not.toBeNull();
expect(match![1]).toContain('Write');
});
// #584 — Sidebar stderr: stderr handler is not empty
test('sidebar-agent.ts stderr handler is not empty', () => {
const content = fs.readFileSync(path.join(ROOT, 'browse', 'src', 'sidebar-agent.ts'), 'utf-8');
// The stderr handler should NOT be an empty arrow function
expect(content).not.toContain("proc.stderr.on('data', () => {})");
});
});