Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
0e52170
feat: add GatewayZ provider with Anthropic API support
vdimarco Jan 4, 2026
f6fc479
chore(dependencies): bump version to 1.0.4 and remove incorrect peer …
vdimarco Jan 4, 2026
e70b0ae
docs: add GatewayZ provider to README
vdimarco Jan 4, 2026
bf581ae
feat: add GatewayZ purple ASCII art splash
vdimarco Jan 4, 2026
4093dd2
chore: update GatewayZ tagline to "Your Gateway to AI"
vdimarco Jan 4, 2026
3ca80dd
fix: add ANTHROPIC_BASE_URL to GatewayZ provider env
vdimarco Jan 4, 2026
ebbaaa9
fix: use authToken mode for GatewayZ provider
vdimarco Jan 4, 2026
1e83e91
fix: configure GatewayZ as OpenRouter-compatible provider
vdimarco Jan 4, 2026
9825652
fix: update GatewayZ to reference OneRouter instead of OpenRouter
vdimarco Jan 4, 2026
498f9dd
fix: use OneRouter model ID format for GatewayZ
vdimarco Jan 4, 2026
42e8d1e
fix: add gatewayz to model mapping validation and UI
vdimarco Jan 4, 2026
642be42
fix: add GatewayZ model placeholders in ModelConfigScreen
vdimarco Jan 4, 2026
51c0dda
fix: update GatewayZ provider features messaging
vdimarco Jan 4, 2026
49e2b82
fix: use provider apiKeyLabel in TUI API key screen
vdimarco Jan 4, 2026
7eb8b8e
fix: auto-fill GatewayZ model defaults in TUI setup
vdimarco Jan 4, 2026
1bde536
fix: use direct Anthropic model IDs without @ sign
vdimarco Jan 4, 2026
d3ba2d1
Merge pull request #1 from Alpaca-Network/terragon/add-anthropic-api-…
vdimarco Jan 4, 2026
354f98b
fix: auto-fill GatewayZ model defaults in CLI quick setup
vdimarco Jan 4, 2026
b32612d
Merge pull request #2 from Alpaca-Network/terragon/add-anthropic-api-…
vdimarco Jan 4, 2026
fe27a43
fix: address PR review comments
vdimarco Jan 5, 2026
53b94cf
fix: address PR review comments
vdimarco Jan 5, 2026
abf8634
Merge pull request #3 from Alpaca-Network/terragon/add-anthropic-api-…
vdimarco Jan 5, 2026
26c9e2d
Merge GatewayZ provider with existing mirror/team mode features
vdimarco Jan 14, 2026
9673950
Merge numman-ali/main with GatewayZ provider support
vdimarco Jan 14, 2026
043dd4f
fix: validate --older-than option to prevent silent NaN comparison
vdimarco Jan 14, 2026
003589b
fix: sync package-lock.json version with package.json
vdimarco Jan 14, 2026
bb52679
Merge pull request #4 from Alpaca-Network/fix-merge-conflicts
vdimarco Jan 18, 2026
522a315
fix: validate --limit option to prevent silent NaN comparison
vdimarco Jan 18, 2026
921e7a2
chore: sync with upstream numman-ali/cc-mirror
vdimarco Jan 18, 2026
22d9e41
fix: make Claude workflows gracefully skip when token not configured
vdimarco Jan 18, 2026
09dc445
fix: escape regex special characters in team-mode-patch fnName
vdimarco Jan 18, 2026
5066db8
Merge pull request #5 from Alpaca-Network/terragon/sync-commits-3bvoy6
vdimarco Jan 18, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 2 additions & 6 deletions .github/workflows/claude-code-review.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,6 @@ on:

jobs:
claude-review:
# Optional: Filter by PR author
# if: |
# github.event.pull_request.user.login == 'external-contributor' ||
# github.event.pull_request.user.login == 'new-developer' ||
# github.event.pull_request.author_association == 'FIRST_TIME_CONTRIBUTOR'

runs-on: ubuntu-latest
permissions:
contents: read
Expand All @@ -32,6 +26,8 @@ jobs:
fetch-depth: 1

- name: Run Claude Code Review
# Only run if CLAUDE_CODE_OAUTH_TOKEN is configured
if: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN != '' }}
id: claude-review
uses: anthropics/claude-code-action@v1
with:
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/claude.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ jobs:
fetch-depth: 1

- name: Run Claude Code
# Only run if CLAUDE_CODE_OAUTH_TOKEN is configured
if: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN != '' }}
id: claude
uses: anthropics/claude-code-action@v1
with:
Expand Down
17 changes: 12 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,12 @@ npx cc-mirror quick --provider minimax --api-key "$MINIMAX_API_KEY"
npx cc-mirror quick --provider openrouter --api-key "$OPENROUTER_API_KEY" \
--model-sonnet "anthropic/claude-sonnet-4-20250514"

# GatewayZ (OneRouter gateway)
npx cc-mirror quick --provider gatewayz --api-key "$GATEWAYZ_API_KEY" \
--model-sonnet "claude-sonnet-4-20250514" \
--model-opus "claude-opus-4-5-20251101" \
--model-haiku "claude-haiku-3-5-20241022"

# Claude Code Router (local LLMs)
npx cc-mirror quick --provider ccrouter
```
Expand Down Expand Up @@ -298,14 +304,14 @@ minimax # Run MiniMax variant
## CLI Options

```
--provider <name> mirror | zai | minimax | openrouter | ccrouter | custom
--provider <name> mirror | zai | minimax | gatewayz | openrouter | ccrouter | custom
--name <name> Variant name (becomes the CLI command)
--api-key <key> Provider API key
--base-url <url> Custom API endpoint
--model-sonnet <name> Map to sonnet model
--model-opus <name> Map to opus model
--model-haiku <name> Map to haiku model
--brand <preset> Theme: auto | zai | minimax | openrouter | ccrouter | mirror
--model-sonnet <name> Map to sonnet model (for providers requiring model mapping)
--model-opus <name> Map to opus model (for providers requiring model mapping)
--model-haiku <name> Map to haiku model (for providers requiring model mapping)
--brand <preset> Theme: auto | zai | minimax | gatewayz | openrouter | ccrouter | mirror
--no-tweak Skip tweakcc theme
--no-prompt-pack Skip provider prompt pack
--verbose Show full tweakcc output during update
Expand All @@ -322,6 +328,7 @@ Each provider includes a custom color theme via [tweakcc](https://github.com/Pie
| **mirror** | Silver/chrome with electric blue |
| **zai** | Dark carbon with gold accents |
| **minimax** | Coral/red/orange spectrum |
| **gatewayz** | Dark portal with violet/purple |
| **openrouter** | Teal/cyan gradient |
| **ccrouter** | Sky blue accents |

Expand Down
11 changes: 0 additions & 11 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

199 changes: 199 additions & 0 deletions src/brands/gatewayz.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
import type { TweakccConfig, Theme } from './types.js';
import { DEFAULT_THEMES } from './defaultThemes.js';
import { formatUserMessage, getUserLabel } from './userLabel.js';

type Rgb = { r: number; g: number; b: number };

const clamp = (value: number) => Math.max(0, Math.min(255, Math.round(value)));

const hexToRgb = (hex: string): Rgb => {
const normalized = hex.replace('#', '').trim();
if (normalized.length === 3) {
const [r, g, b] = normalized.split('');
return {
r: clamp(parseInt(r + r, 16)),
g: clamp(parseInt(g + g, 16)),
b: clamp(parseInt(b + b, 16)),
};
}
if (normalized.length !== 6) {
throw new Error(`Unsupported hex color: ${hex}`);
}
return {
r: clamp(parseInt(normalized.slice(0, 2), 16)),
g: clamp(parseInt(normalized.slice(2, 4), 16)),
b: clamp(parseInt(normalized.slice(4, 6), 16)),
};
};

const rgb = (hex: string) => {
const { r, g, b } = hexToRgb(hex);
return `rgb(${r},${g},${b})`;
};

const mix = (hexA: string, hexB: string, weight: number) => {
const a = hexToRgb(hexA);
const b = hexToRgb(hexB);
const w = Math.max(0, Math.min(1, weight));
return `rgb(${clamp(a.r + (b.r - a.r) * w)},${clamp(a.g + (b.g - a.g) * w)},${clamp(a.b + (b.b - a.b) * w)})`;
};

const lighten = (hex: string, weight: number) => mix(hex, '#ffffff', weight);

// GatewayZ palette - violet/purple gateway theme with tech accents
const palette = {
base: '#1a1625',
surface: '#221d2e',
panel: '#2a2438',
border: '#3d3650',
borderStrong: '#524a68',
text: '#e8e6ec',
textMuted: '#c4c0cc',
textDim: '#8a8494',
// Primary violet/purple gateway colors
violet: '#8b5cf6',
violetSoft: '#a78bfa',
violetDeep: '#6d28d9',
// Accent colors
cyan: '#22d3ee',
cyanSoft: '#67e8f9',
green: '#34d399',
red: '#f87171',
orange: '#fb923c',
pink: '#f472b6',
};

const theme: Theme = {
name: 'GatewayZ Portal',
id: 'gatewayz-portal',
colors: {
autoAccept: rgb(palette.green),
bashBorder: rgb(palette.violet),
claude: rgb(palette.violet),
claudeShimmer: rgb(palette.violetSoft),
claudeBlue_FOR_SYSTEM_SPINNER: rgb(palette.cyan),
claudeBlueShimmer_FOR_SYSTEM_SPINNER: rgb(palette.cyanSoft),
permission: rgb(palette.cyan),
permissionShimmer: rgb(palette.cyanSoft),
planMode: rgb(palette.green),
ide: rgb(palette.cyanSoft),
promptBorder: rgb(palette.border),
promptBorderShimmer: rgb(palette.borderStrong),
text: rgb(palette.text),
inverseText: rgb(palette.base),
inactive: rgb(palette.textDim),
subtle: rgb(palette.border),
suggestion: rgb(palette.cyanSoft),
remember: rgb(palette.violet),
background: rgb(palette.base),
success: rgb(palette.green),
error: rgb(palette.red),
warning: rgb(palette.orange),
warningShimmer: lighten(palette.orange, 0.25),
diffAdded: mix(palette.base, palette.green, 0.18),
diffRemoved: mix(palette.base, palette.red, 0.18),
diffAddedDimmed: mix(palette.base, palette.green, 0.1),
diffRemovedDimmed: mix(palette.base, palette.red, 0.1),
diffAddedWord: mix(palette.base, palette.green, 0.45),
diffRemovedWord: mix(palette.base, palette.red, 0.45),
diffAddedWordDimmed: mix(palette.base, palette.green, 0.3),
diffRemovedWordDimmed: mix(palette.base, palette.red, 0.3),
red_FOR_SUBAGENTS_ONLY: rgb(palette.red),
blue_FOR_SUBAGENTS_ONLY: rgb(palette.violetDeep),
green_FOR_SUBAGENTS_ONLY: rgb(palette.green),
yellow_FOR_SUBAGENTS_ONLY: rgb(palette.orange),
purple_FOR_SUBAGENTS_ONLY: rgb(palette.violet),
orange_FOR_SUBAGENTS_ONLY: rgb(palette.orange),
pink_FOR_SUBAGENTS_ONLY: rgb(palette.pink),
cyan_FOR_SUBAGENTS_ONLY: rgb(palette.cyan),
professionalBlue: rgb(palette.cyanSoft),
rainbow_red: rgb(palette.red),
rainbow_orange: rgb(palette.orange),
rainbow_yellow: lighten(palette.orange, 0.2),
rainbow_green: rgb(palette.green),
rainbow_blue: rgb(palette.cyan),
rainbow_indigo: rgb(palette.violetDeep),
rainbow_violet: rgb(palette.violet),
rainbow_red_shimmer: lighten(palette.red, 0.35),
rainbow_orange_shimmer: lighten(palette.orange, 0.35),
rainbow_yellow_shimmer: lighten(palette.orange, 0.4),
rainbow_green_shimmer: lighten(palette.green, 0.35),
rainbow_blue_shimmer: lighten(palette.cyan, 0.35),
rainbow_indigo_shimmer: lighten(palette.violetDeep, 0.35),
rainbow_violet_shimmer: lighten(palette.violet, 0.35),
clawd_body: rgb(palette.violet),
clawd_background: rgb(palette.base),
userMessageBackground: rgb(palette.panel),
bashMessageBackgroundColor: rgb(palette.surface),
memoryBackgroundColor: rgb(palette.panel),
rate_limit_fill: rgb(palette.violet),
rate_limit_empty: rgb(palette.borderStrong),
},
};

export const buildGatewayZTweakccConfig = (): TweakccConfig => ({
ccVersion: '',
ccInstallationPath: null,
lastModified: new Date().toISOString(),
changesApplied: false,
hidePiebaldAnnouncement: true,
settings: {
themes: [theme, ...DEFAULT_THEMES],
thinkingVerbs: {
format: '{}... ',
verbs: [
'Routing',
'Tunneling',
'Bridging',
'Connecting',
'Relaying',
'Forwarding',
'Proxying',
'Streaming',
'Syncing',
'Processing',
'Resolving',
'Mapping',
'Transferring',
'Linking',
],
},
thinkingStyle: {
updateInterval: 115,
phases: ['◇', '◈', '◆', '◈'],
reverseMirror: false,
},
userMessageDisplay: {
format: formatUserMessage(getUserLabel()),
styling: ['bold'],
foregroundColor: 'default',
backgroundColor: 'default',
borderStyle: 'topBottomBold',
borderColor: rgb(palette.violet),
paddingX: 1,
paddingY: 0,
fitBoxToContent: true,
},
inputBox: {
removeBorder: true,
},
misc: {
showTweakccVersion: false,
showPatchesApplied: false,
expandThinkingBlocks: true,
enableConversationTitle: true,
hideStartupBanner: true,
hideCtrlGToEditPrompt: true,
hideStartupClawd: true,
increaseFileReadLimit: true,
},
toolsets: [
{
name: 'gatewayz',
allowedTools: '*',
},
],
defaultToolset: 'gatewayz',
planModeToolset: 'gatewayz',
},
});
7 changes: 7 additions & 0 deletions src/brands/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { TweakccConfig } from './types.js';
import { buildZaiTweakccConfig } from './zai.js';
import { buildMinimaxTweakccConfig } from './minimax.js';
import { buildGatewayZTweakccConfig } from './gatewayz.js';
import { buildOpenRouterTweakccConfig } from './openrouter.js';
import { buildCCRouterTweakccConfig } from './ccrouter.js';
import { buildMirrorTweakccConfig } from './mirror.js';
Expand All @@ -25,6 +26,12 @@ const BRAND_PRESETS: Record<string, BrandPreset> = {
description: 'Vibrant spectrum accents (red/orange/pink/violet) with MiniMax toolset label.',
buildTweakccConfig: buildMinimaxTweakccConfig,
},
gatewayz: {
key: 'gatewayz',
label: 'GatewayZ Portal',
description: 'Dark portal palette with violet/purple accents and cyan highlights.',
buildTweakccConfig: buildGatewayZTweakccConfig,
},
openrouter: {
key: 'openrouter',
label: 'OpenRouter Teal',
Expand Down
Loading