Skip to content

Commit 546ccec

Browse files
committed
feat(coordinator): add coordinator UI and launch fixes
1 parent 6bc4b7d commit 546ccec

64 files changed

Lines changed: 4972 additions & 2152 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@ jobs:
1010
quality:
1111
runs-on: ubuntu-latest
1212
steps:
13-
- uses: actions/checkout@v4
13+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
1414

15-
- uses: actions/setup-node@v4
15+
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
1616
with:
17-
node-version: 'lts/*'
17+
node-version: '22'
1818
cache: npm
1919

2020
- run: npm ci

.github/workflows/release.yml

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@ jobs:
1414
outputs:
1515
release_id: ${{ steps.create.outputs.id }}
1616
steps:
17-
- uses: actions/checkout@v4
17+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
1818

1919
- name: Create draft release
2020
id: create
21-
uses: softprops/action-gh-release@v2
21+
uses: softprops/action-gh-release@3bb12739c298aeb8a4eeaf626c5b8d85266b0e65 # v2
2222
with:
2323
draft: true
2424
generate_release_notes: true
@@ -27,18 +27,18 @@ jobs:
2727
needs: create-release
2828
runs-on: ubuntu-22.04
2929
steps:
30-
- uses: actions/checkout@v4
30+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
3131

32-
- uses: actions/setup-node@v4
32+
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
3333
with:
34-
node-version: 'lts/*'
34+
node-version: '22'
3535
cache: npm
3636

3737
- run: npm ci
3838
- run: npm run build -- --publish never
3939

4040
- name: Upload artifacts
41-
uses: softprops/action-gh-release@v2
41+
uses: softprops/action-gh-release@3bb12739c298aeb8a4eeaf626c5b8d85266b0e65 # v2
4242
with:
4343
tag_name: ${{ github.ref_name }}
4444
files: |
@@ -50,11 +50,11 @@ jobs:
5050
needs: create-release
5151
runs-on: macos-latest
5252
steps:
53-
- uses: actions/checkout@v4
53+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
5454

55-
- uses: actions/setup-node@v4
55+
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
5656
with:
57-
node-version: 'lts/*'
57+
node-version: '22'
5858
cache: npm
5959

6060
- name: Import code signing certificate
@@ -98,7 +98,7 @@ jobs:
9898
run: npm run build -- --universal --publish never
9999

100100
- name: Upload artifacts
101-
uses: softprops/action-gh-release@v2
101+
uses: softprops/action-gh-release@3bb12739c298aeb8a4eeaf626c5b8d85266b0e65 # v2
102102
with:
103103
tag_name: ${{ github.ref_name }}
104104
files: release/*.dmg

.husky/commit-msg

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#!/bin/sh
2+
commit_msg=$(cat "$1")
3+
4+
# Allow merge commits, revert commits, and fixup/squash commits
5+
if echo "$commit_msg" | grep -qE "^(Merge|Revert|fixup!|squash!)"; then
6+
exit 0
7+
fi
8+
9+
# Enforce conventional commit format: type(scope): message
10+
if ! echo "$commit_msg" | grep -qE "^(feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert)(\(.+\))?: .{1,}"; then
11+
echo ""
12+
echo "Invalid commit message format."
13+
echo "Expected: type(scope): description"
14+
echo "Examples:"
15+
echo " feat(coordinator): add MCP status indicator"
16+
echo " fix(terminal): restore PTY preservation on reload"
17+
echo " chore: update dependencies"
18+
echo ""
19+
echo "Valid types: feat fix docs style refactor perf test build ci chore revert"
20+
exit 1
21+
fi

.husky/pre-commit

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,18 @@
11
#!/bin/sh
22
npx lint-staged
33
npm run check
4+
5+
# Verify package-lock.json is committed and in sync with package.json
6+
if git diff --cached --name-only | grep -q "package\.json$"; then
7+
if ! git diff --cached --name-only | grep -q "package-lock\.json$"; then
8+
echo "Error: package.json changed without updating package-lock.json"
9+
echo "Run 'npm install' to update the lockfile"
10+
exit 1
11+
fi
12+
fi
13+
14+
# Ensure package-lock.json is not gitignored (supply chain: lockfile must be tracked)
15+
if git check-ignore -q package-lock.json 2>/dev/null; then
16+
echo "Error: package-lock.json must not be gitignored — it provides integrity hashes"
17+
exit 1
18+
fi

.husky/pre-push

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,11 @@
11
#!/bin/sh
22
npm run check
3+
4+
echo "Running tests before push..."
5+
npm test
6+
if [ $? -ne 0 ]; then
7+
echo ""
8+
echo "Tests failed. Fix failing tests before pushing."
9+
echo "Run 'npm test' to see details."
10+
exit 1
11+
fi

electron/ipc/agents.ts

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ interface AgentDef {
1414
description: string;
1515
available?: boolean;
1616
prompt_ready_delay_ms?: number;
17-
mcp_config_flag?: string; // CLI flag to pass MCP config file path; omit if agent doesn't support it
1817
}
1918

2019
const DEFAULT_AGENTS: AgentDef[] = [
@@ -26,7 +25,6 @@ const DEFAULT_AGENTS: AgentDef[] = [
2625
resume_args: ['--continue'],
2726
skip_permissions_args: ['--dangerously-skip-permissions'],
2827
description: "Anthropic's Claude Code CLI agent",
29-
mcp_config_flag: '--mcp-config',
3028
},
3129
{
3230
id: 'codex',
@@ -36,7 +34,6 @@ const DEFAULT_AGENTS: AgentDef[] = [
3634
resume_args: ['resume', '--last'],
3735
skip_permissions_args: ['--dangerously-bypass-approvals-and-sandbox'],
3836
description: "OpenAI's Codex CLI agent",
39-
mcp_config_flag: '--config',
4037
},
4138
{
4239
id: 'gemini',
@@ -88,14 +85,7 @@ const AGENT_CACHE_TTL = 30_000;
8885
export function getSkipPermissionsArgs(command: string): string[] {
8986
const base = path.basename(command);
9087
const agent = DEFAULT_AGENTS.find((a) => a.command === base || a.command === command);
91-
return agent ? [...agent.skip_permissions_args] : [];
92-
}
93-
94-
export function getMcpConfigArgs(command: string, configPath: string): string[] {
95-
const base = path.basename(command);
96-
const agent = DEFAULT_AGENTS.find((a) => a.command === base || a.command === command);
97-
if (!agent?.mcp_config_flag) return [];
98-
return [agent.mcp_config_flag, configPath];
88+
return agent ? agent.skip_permissions_args : [];
9989
}
10090

10191
export async function listAgents(): Promise<AgentDef[]> {

electron/ipc/git.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1424,10 +1424,16 @@ export async function getWorktreeStatus(
14241424
if (!fs.existsSync(worktreePath)) {
14251425
return { has_committed_changes: false, has_uncommitted_changes: false, current_branch: null };
14261426
}
1427-
const { stdout: statusOut } = await exec('git', ['status', '--porcelain'], {
1428-
cwd: worktreePath,
1429-
maxBuffer: MAX_BUFFER,
1430-
});
1427+
let statusOut: string;
1428+
try {
1429+
({ stdout: statusOut } = await exec('git', ['status', '--porcelain'], {
1430+
cwd: worktreePath,
1431+
maxBuffer: MAX_BUFFER,
1432+
}));
1433+
} catch {
1434+
// Worktree removed between existsSync and exec (race condition)
1435+
return { has_committed_changes: false, has_uncommitted_changes: false, current_branch: null };
1436+
}
14311437
const hasUncommittedChanges = statusOut.trim().length > 0;
14321438

14331439
const currentBranch = await getCurrentBranchName(worktreePath).catch(() => null);
@@ -1883,6 +1889,7 @@ export async function getBranchCommits(
18831889
baseBranch?: string,
18841890
recentFallback?: number,
18851891
): Promise<CommitInfo[]> {
1892+
if (!fs.existsSync(worktreePath)) return [];
18861893
const mergeBase = await detectMergeBase(worktreePath, 'HEAD', baseBranch);
18871894
try {
18881895
const { stdout } = await exec(

0 commit comments

Comments
 (0)