From e287da723d123090e1341397ffa78eb51ef37266 Mon Sep 17 00:00:00 2001 From: Gravirei Date: Thu, 1 Oct 2026 10:50:44 +0600 Subject: [PATCH 1/2] chore(rebrand): update Gitlawb references to Twigpine (#2246) The GitHub org has been renamed to Twigpine, so point repo URLs, badges, CI repo-identity guards, and user-facing sponsor/partner labels at the new name. Scope is deliberately limited to references that are safe to change today: - GitHub URLs (github.com, api.github.com, raw.githubusercontent.com), including the skills registry and release-please release notes - The release-please release trigger, which gates on the repo slug and would otherwise stop publishing - User-visible display strings: gateway label/name, AI/ML API partner name, sponsored-tip sponsor, and docs/site prose Left on the old name because the rename has not landed for them: - `@gitlawb/openclaude` npm scope (the package does not exist on npm) - opengateway/ads/docs subdomains, which resolve only under gitlawb.com - The `gitlawb-opengateway` preset id, tip ids, and gateway file names, which are persisted in user config and sent on the wire Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/ISSUE_TEMPLATE/config.yml | 2 +- .github/pull_request_template.md | 2 +- .github/workflows/release.yml | 4 +- ANDROID_INSTALL.md | 2 +- CONTRIBUTING.md | 12 +++--- README.md | 28 +++++++------- docs/advanced-setup.md | 8 ++-- docs/integrations/how-to/add-gateway.md | 2 +- docs/integrations/overview.md | 2 +- docs/non-technical-setup.md | 4 +- docs/skills.md | 4 +- package.json | 2 +- scripts/build.ts | 8 ++-- scripts/missing-module-stub.test.ts | 2 +- src/cli/handlers/skills.test.ts | 4 +- src/cli/handlers/skillsInstall.ts | 2 +- .../install-github-app/repoSlug.test.ts | 30 +++++++-------- src/commands/model/model.test.tsx | 22 +++++------ src/components/Feedback.tsx | 2 +- src/components/HelpV2/HelpV2.tsx | 2 +- src/components/ProviderManager.test.tsx | 4 +- src/components/StartupScreen.ts | 2 +- src/components/mcp/MCPSettings.tsx | 2 +- src/constants/brand.ts | 4 +- src/constants/promptIdentity.test.ts | 2 +- src/constants/prompts.ts | 2 +- src/entrypoints/cli.test.ts | 2 +- src/entrypoints/sdk/stubLeakDetection.ts | 2 +- .../notifs/npmDeprecationNotification.ts | 2 +- src/integrations/aimlapi/config.test.ts | 4 +- src/integrations/aimlapi/config.ts | 6 +-- src/integrations/aimlapi/topup.test.ts | 16 ++++---- src/integrations/artifactGenerator.ts | 2 +- src/integrations/discoveryService.test.ts | 6 +-- src/integrations/gateways/aimlapi.ts | 2 +- .../gateways/gitlawb-opengateway.ts | 10 ++--- .../integrationManifest.generated.ts | 6 +-- src/screens/ResumeConversation.test.ts | 6 +-- src/services/ads.ts | 2 +- src/services/api/bootstrap.test.ts | 2 +- src/services/api/client.test.ts | 2 +- .../requestExecutor.integration.test.ts | 4 +- src/services/api/providerConfig.local.test.ts | 2 +- src/services/tips/gitlawbEarn.test.ts | 10 ++--- src/services/tips/gitlawbEarn.ts | 26 ++++++------- src/services/tips/tipScheduler.test.ts | 2 +- src/services/tips/tipScheduler.ts | 2 +- src/services/tips/types.ts | 2 +- src/tools/WebSearchTool/providers/custom.ts | 2 +- src/utils/attribution.test.ts | 2 +- src/utils/attribution.ts | 4 +- src/utils/conversationRecovery.test.ts | 8 ++-- src/utils/http.test.ts | 2 +- src/utils/http.ts | 2 +- src/utils/model/routeCatalogOptions.test.ts | 4 +- src/utils/providerAutoDetect.ts | 6 +-- src/utils/providerProfile.test.ts | 10 ++--- src/utils/providerProfile.ts | 2 +- src/utils/providerProfiles.test.ts | 2 +- src/utils/providerProfiles.ts | 2 +- src/utils/releaseNotes.test.ts | 6 +-- src/utils/releaseNotes.ts | 2 +- src/utils/reportTask.test.ts | 36 +++++++++--------- src/utils/theme.ts | 2 +- src/utils/version.ts | 2 +- .../openclaude-vscode/package.json | 2 +- .../openclaude-vscode/src/extension.js | 4 +- web/astro.config.mjs | 2 +- web/public/llms.txt | 32 ++++++++-------- .../partners/{gitlawb.png => twigpine.png} | Bin web/src/components/Footer.astro | 10 ++--- web/src/components/Nav.astro | 2 +- web/src/data/configuration.ts | 2 +- web/src/data/partners.ts | 6 +-- web/src/data/providers.ts | 2 +- web/src/data/site.ts | 10 +++-- web/src/layouts/DocsLayout.astro | 2 +- web/src/pages/docs/index.astro | 4 +- web/src/pages/index.astro | 4 +- web/src/styles/global.css | 6 +-- 80 files changed, 232 insertions(+), 228 deletions(-) rename web/public/partners/{gitlawb.png => twigpine.png} (100%) diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 0f65b55022..7f3d77defb 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,5 +1,5 @@ blank_issues_enabled: true contact_links: - name: OpenClaude Discussions - url: https://github.com/Gitlawb/openclaude/discussions + url: https://github.com/Twigpine/openclaude/discussions about: Use Discussions for setup help, questions, ideas, and community conversation. diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index a71436b981..06b4794eec 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -10,7 +10,7 @@ ## Testing -- [ ] I ran the required [local preflight](https://github.com/Gitlawb/openclaude/blob/main/CONTRIBUTING.md#validation). +- [ ] I ran the required [local preflight](https://github.com/Twigpine/openclaude/blob/main/CONTRIBUTING.md#validation). - exact commands and results: - focused tests: - documented skipped checks, platform limitations, or verified pre-existing failures: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 906012118b..7994e5bf11 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -11,7 +11,7 @@ concurrency: jobs: release-please: - if: ${{ github.repository == 'Gitlawb/openclaude' }} + if: ${{ github.repository == 'Twigpine/openclaude' }} name: Release Please runs-on: ubuntu-latest permissions: @@ -164,7 +164,7 @@ jobs: echo "## Released ${{ needs.release-please.outputs.tag_name }}" echo echo "- npm: https://www.npmjs.com/package/@gitlawb/openclaude" - echo "- GitHub: https://github.com/Gitlawb/openclaude/releases/tag/${{ needs.release-please.outputs.tag_name }}" + echo "- GitHub: https://github.com/Twigpine/openclaude/releases/tag/${{ needs.release-please.outputs.tag_name }}" } >> "$GITHUB_STEP_SUMMARY" docker: diff --git a/ANDROID_INSTALL.md b/ANDROID_INSTALL.md index ca49175a16..2e77fb8cea 100644 --- a/ANDROID_INSTALL.md +++ b/ANDROID_INSTALL.md @@ -42,7 +42,7 @@ node --version # should be v20+ ### Step 3 — Clone OpenClaude ```bash -git clone https://github.com/Gitlawb/openclaude.git +git clone https://github.com/Twigpine/openclaude.git cd openclaude npm install npm link diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7f6a99b506..4a745a0918 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -26,8 +26,8 @@ OpenClaude is a rapidly evolving open-source coding-agent CLI with support for m ## Before You Start -- Search existing [issues](https://github.com/Gitlawb/openclaude/issues) and [discussions](https://github.com/Gitlawb/openclaude/discussions) before opening a new thread. -- Check [open pull requests](https://github.com/Gitlawb/openclaude/pulls) for work that overlaps with your contribution. If a PR already exists that addresses the same change, open an issue or discussion first to align on direction — duplicate PRs may be closed without review. +- Search existing [issues](https://github.com/Twigpine/openclaude/issues) and [discussions](https://github.com/Twigpine/openclaude/discussions) before opening a new thread. +- Check [open pull requests](https://github.com/Twigpine/openclaude/pulls) for work that overlaps with your contribution. If a PR already exists that addresses the same change, open an issue or discussion first to align on direction — duplicate PRs may be closed without review. - Use issues for confirmed bugs and actionable feature work. - Use discussions for setup help, ideas, and general community conversation. - For larger changes, open an issue first so the scope is clear before implementation. @@ -114,8 +114,8 @@ If you find yourself getting fix requests on every round, treat that as a signal We are proactive about closing duplicate PRs. Before submitting, **it is your responsibility to check** whether a similar PR already exists: -- Search [open pull requests](https://github.com/Gitlawb/openclaude/pulls) for related work -- Check [closed pull requests](https://github.com/Gitlawb/openclaude/pulls?q=is%3Apr+is%3Aclosed) to see if similar work was previously addressed or declined +- Search [open pull requests](https://github.com/Twigpine/openclaude/pulls) for related work +- Check [closed pull requests](https://github.com/Twigpine/openclaude/pulls?q=is%3Apr+is%3Aclosed) to see if similar work was previously addressed or declined - If you find an existing PR, engage in that thread rather than opening a new one Duplicate PRs will likely be closed without review or follow-up. This isn't personal — it's about keeping the review queue focused and efficient. @@ -268,7 +268,7 @@ bun run typecheck:type-tests node bin/openclaude --version bun run test:provider npm run test:provider-recommendation -git fetch https://github.com/Gitlawb/openclaude.git main +git fetch https://github.com/Twigpine/openclaude.git main bun run security:pr-scan -- --base FETCH_HEAD --head HEAD ``` @@ -309,7 +309,7 @@ bun run web:build Notes on the local preflight: - `bun run check` already builds the CLI and includes smoke, deadcode, and the full unit pass (`test:full`) — do not run those separately, or you execute work twice. -- Fetching upstream `main` by URL avoids assuming that a fork checkout's `origin` points at Gitlawb/openclaude. `FETCH_HEAD` is the fetched upstream tip. The scan deliberately uses local `HEAD` so it includes commits that have not been pushed yet; CI uses the pushed PR head SHA after the push. +- Fetching upstream `main` by URL avoids assuming that a fork checkout's `origin` points at Twigpine/openclaude. `FETCH_HEAD` is the fetched upstream tip. The scan deliberately uses local `HEAD` so it includes commits that have not been pushed yet; CI uses the pushed PR head SHA after the push. - The web CI job remains unconditional as an integration backstop. Contributors do not need to run the web suite locally for changes that cannot affect the site. - This preflight covers the same command families as CI, but it does not reproduce CI exactly in one shell. CI runs the main checks under Node 22 and 24.11.x, separately builds and launches under exact Node 22.0.0, and executes every job on a clean runner. diff --git a/README.md b/README.md index a26fe90666..0fcb4defe5 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,9 @@ OpenClaude — Open terminal for any LLM

- Gitlawb%2Fopenclaude | Trendshift - Gitlawb%2Fopenclaude | Trendshift - Gitlawb%2Fopenclaude | Trendshift + Twigpine%2Fopenclaude | Trendshift + Twigpine%2Fopenclaude | Trendshift + Twigpine%2Fopenclaude | Trendshift

@@ -12,16 +12,16 @@ OpenClaude is an open-source coding-agent CLI for cloud and local model provider Use OpenAI-compatible APIs, Gemini, GitHub Models, Codex OAuth, Codex, Ollama, Atomic Chat, and other supported backends while keeping one terminal-first workflow: prompts, tools, agents, MCP, slash commands, and streaming output. -[![PR Checks](https://github.com/Gitlawb/openclaude/actions/workflows/pr-checks.yml/badge.svg?branch=main)](https://github.com/Gitlawb/openclaude/actions/workflows/pr-checks.yml) -[![Release](https://img.shields.io/github/v/tag/Gitlawb/openclaude?label=release&color=0ea5e9)](https://github.com/Gitlawb/openclaude/tags) +[![PR Checks](https://github.com/Twigpine/openclaude/actions/workflows/pr-checks.yml/badge.svg?branch=main)](https://github.com/Twigpine/openclaude/actions/workflows/pr-checks.yml) +[![Release](https://img.shields.io/github/v/tag/Twigpine/openclaude?label=release&color=0ea5e9)](https://github.com/Twigpine/openclaude/tags) [![npm downloads](https://img.shields.io/npm/dm/@gitlawb/openclaude)](https://www.npmjs.com/package/@gitlawb/openclaude) -[![Discussions](https://img.shields.io/badge/discussions-open-7c3aed)](https://github.com/Gitlawb/openclaude/discussions) +[![Discussions](https://img.shields.io/badge/discussions-open-7c3aed)](https://github.com/Twigpine/openclaude/discussions) [![Discord](https://img.shields.io/badge/Discord-join-5865F2?logo=discord&logoColor=white)](https://discord.gg/k68zFR6AcB) [![X](https://img.shields.io/badge/X-@gitlawb-000000?logo=x&logoColor=white)](https://x.com/gitlawb) [![Security Policy](https://img.shields.io/badge/security-policy-0f766e)](SECURITY.md) [![License](https://img.shields.io/badge/license-MIT-2563eb)](LICENSE) -OpenClaude is also mirrored to GitLawb: +OpenClaude is also mirrored to Twigpine: [gitlawb.com/node/repos/z6MkqDnb/openclaude](https://gitlawb.com/node/repos/z6MkqDnb/openclaude) [Quick Start](#quick-start) | [Setup Guides](#setup-guides) | [Providers](#supported-providers) | [Development](#development) | [VS Code Extension](#vs-code-extension) | [Partners](#partners) | [Community](#community) @@ -31,8 +31,8 @@ OpenClaude is also mirrored to GitLawb: - + @@ -322,7 +322,7 @@ Advanced and source-build guides: | GitHub Models | `/onboard-github` | Interactive onboarding with saved credentials | | Codex OAuth | `/provider` | Opens ChatGPT sign-in in your browser and stores Codex credentials securely | | Codex | `/provider` | Uses existing Codex CLI auth, OpenClaude secure storage, or env credentials | -| Gitlawb Opengateway | Startup default, `/provider`, or env vars | Smart gateway at `https://opengateway.gitlawb.com/v1`; requires an API key from https://gitlawb.com/opengateway/keys and routes Xiaomi MiMo and GMI Cloud partner models by `OPENAI_MODEL` | +| Twigpine Opengateway | Startup default, `/provider`, or env vars | Smart gateway at `https://opengateway.gitlawb.com/v1`; requires an API key from https://gitlawb.com/opengateway/keys and routes Xiaomi MiMo and GMI Cloud partner models by `OPENAI_MODEL` | | OpenCode Zen | `/provider` or env vars | Pay-as-you-go AI gateway (48 models); uses `OPENCODE_API_KEY` via `https://opencode.ai/zen/v1`; shared key with OpenCode Go | | OpenCode Go | `/provider` or env vars | $10/mo subscription for open models (13 models); uses `OPENCODE_API_KEY` via `https://opencode.ai/zen/go/v1`; shared key with OpenCode Zen | | Xiaomi MiMo | `/provider` or env vars | OpenAI-compatible API at `https://mimo.mi.com`; uses `MIMO_API_KEY` and defaults to `mimo-v2.5-pro` | @@ -375,7 +375,7 @@ OpenClaude supports multiple providers, but behavior is not identical across all - Smaller local models can struggle with long multi-step tool flows - Some providers impose lower output caps than the CLI defaults, and OpenClaude adapts where possible - AI/ML API uses the OpenAI-compatible route, defaults to `gpt-4o`, and only surfaces chat-capable models from its public catalog -- Gitlawb Opengateway is the fresh-install startup default and requires an API key from https://gitlawb.com/opengateway/keys. It uses one OpenAI-compatible base URL; switch between `mimo-*` and `google/gemini-3.1-flash-lite-preview` with `/model`, and do not pin the base URL to `/v1/xiaomi-mimo`. +- Twigpine Opengateway is the fresh-install startup default and requires an API key from https://gitlawb.com/opengateway/keys. It uses one OpenAI-compatible base URL; switch between `mimo-*` and `google/gemini-3.1-flash-lite-preview` with `/model`, and do not pin the base URL to `/v1/xiaomi-mimo`. - Z.AI GLM Coding Plan uses `https://api.z.ai/api/coding/paas/v4` with `glm-5.2` by default. On that direct route, GLM-5.3-Flash is selectable as `glm-5.3-flash` and accepts image input. Its OpenClaude effort choices are `low`, `high`, and `xhigh`, with `xhigh` requesting Z.AI `max`; GLM-5.3 and the existing GLM-5.2 query controls remain supported. These capabilities are not claimed for gateways that happen to carry the same model name. - Xiaomi MiMo uses `api-key` header auth on the direct OpenAI-compatible route and currently does not support `/usage` reporting in OpenClaude - GitHub Copilot serializes sub-agent execution by default to reduce Premium Request consumption — see [Agent Routing and Step Limits](docs/agent-routing.md#github-copilot-sub-agent-optimization) for tuning @@ -501,8 +501,8 @@ If you believe you found a security issue, see [SECURITY.md](SECURITY.md). ## Community -- Use [GitHub Discussions](https://github.com/Gitlawb/openclaude/discussions) for Q&A, ideas, and community conversation -- Use [GitHub Issues](https://github.com/Gitlawb/openclaude/issues) for confirmed bugs and actionable feature work +- Use [GitHub Discussions](https://github.com/Twigpine/openclaude/discussions) for Q&A, ideas, and community conversation +- Use [GitHub Issues](https://github.com/Twigpine/openclaude/issues) for confirmed bugs and actionable feature work - Join the [Discord](https://discord.gg/k68zFR6AcB) to chat with the community in real time - Follow [@gitlawb on X](https://x.com/gitlawb) for updates and announcements diff --git a/docs/advanced-setup.md b/docs/advanced-setup.md index ca453757aa..6e24a57bff 100644 --- a/docs/advanced-setup.md +++ b/docs/advanced-setup.md @@ -18,7 +18,7 @@ npm install -g @gitlawb/openclaude@latest Use Bun `1.3.13` or newer for source builds. Older Bun versions can fail during `bun run build`. ```bash -git clone https://github.com/Gitlawb/openclaude.git +git clone https://github.com/Twigpine/openclaude.git cd openclaude bun install @@ -29,7 +29,7 @@ npm link ### Option C: Run directly with Bun ```bash -git clone https://github.com/Gitlawb/openclaude.git +git clone https://github.com/Twigpine/openclaude.git cd openclaude bun install @@ -276,7 +276,7 @@ MiMo, MiniMax, Qwen). Uses the same `OPENCODE_API_KEY` as OpenCode Zen. OpenClaude automatically sends the session and product identity headers that OpenCode Go requires for prompt caching and traffic attribution. -### Gitlawb Opengateway +### Twigpine Opengateway ```bash export CLAUDE_CODE_USE_OPENAI=1 @@ -689,7 +689,7 @@ command-injection validation, and sensitive-file / auto-edit guards. These are conservative by design, but a few of them can surface as refusals or approval prompts for entirely benign, routine coding tasks (e.g. editing `.gitmodules`, running a build script that contains `$(date)`, or writing a CTF port scanner). -See [issue #1616](https://github.com/Gitlawb/openclaude/issues/1616). +See [issue #1616](https://github.com/Twigpine/openclaude/issues/1616). Set `OPENCLAUDE_SAFETY_LEVEL` to dial strictness without changing behavior for everyone: diff --git a/docs/integrations/how-to/add-gateway.md b/docs/integrations/how-to/add-gateway.md index 2d7dae1539..8757925e93 100644 --- a/docs/integrations/how-to/add-gateway.md +++ b/docs/integrations/how-to/add-gateway.md @@ -453,7 +453,7 @@ Use `discoveryRefreshMode` to match the operational shape of the route: If an authenticated inference route exposes a public model endpoint, set `catalog.discovery.requiresAuth` to `false` while keeping `setup.requiresAuth` -enabled. OpenRouter and Gitlawb Opengateway use this split: model listing is +enabled. OpenRouter and Twigpine Opengateway use this split: model listing is keyless, but inference still requires an API key. Avoid combining `discoveryRefreshMode: 'startup'` with an `openai-compatible-models` readiness probe when both execute the same request, because that doubles startup traffic. diff --git a/docs/integrations/overview.md b/docs/integrations/overview.md index dcd759b63d..df2cc12c96 100644 --- a/docs/integrations/overview.md +++ b/docs/integrations/overview.md @@ -153,7 +153,7 @@ model is normalized. ### Public aggregator model discovery -OpenRouter and Gitlawb Opengateway use public model-list endpoints to keep their +OpenRouter and Twigpine Opengateway use public model-list endpoints to keep their hybrid catalogs current. Listing models does not require credentials, but chat and other inference requests still require the provider's API key. OpenRouter refreshes stale discovery data in the background. Opengateway refreshes once at diff --git a/docs/non-technical-setup.md b/docs/non-technical-setup.md index ce4917dcb5..a5eff255ea 100644 --- a/docs/non-technical-setup.md +++ b/docs/non-technical-setup.md @@ -153,10 +153,10 @@ If you want source builds, advanced provider profiles, diagnostics, or Bun-based ## Getting Help -- **GitHub Discussions**: https://github.com/Gitlawb/openclaude/discussions +- **GitHub Discussions**: https://github.com/Twigpine/openclaude/discussions Use this for Q&A, setup help, and community conversation. -- **GitHub Issues**: https://github.com/Gitlawb/openclaude/issues +- **GitHub Issues**: https://github.com/Twigpine/openclaude/issues Use this for confirmed bugs and feature requests. ### Quick diagnostic check diff --git a/docs/skills.md b/docs/skills.md index 916d453963..59984a7e5d 100644 --- a/docs/skills.md +++ b/docs/skills.md @@ -15,7 +15,7 @@ openclaude skills verify [options] Check installed skills for re ## Install from the registry -The default registry is the Gitlawb Skill Hub, published as `registry.json` in [Gitlawb/openclaude-skills](https://github.com/Gitlawb/openclaude-skills). +The default registry is the Twigpine Skill Hub, published as `registry.json` in [Twigpine/openclaude-skills](https://github.com/Twigpine/openclaude-skills). Install a skill by its registry id: ```bash @@ -76,7 +76,7 @@ ci-fix enabled Diagnoses and fixes CI pipeline failures. ```text $ openclaude skills verify -Found 2 installed skills. Revocation list: https://raw.githubusercontent.com/Gitlawb/openclaude-skills/main/revocations.json +Found 2 installed skills. Revocation list: https://raw.githubusercontent.com/Twigpine/openclaude-skills/main/revocations.json ci-fix ok hand-made skipped (no registry metadata) eyebrow not found; install it to check skill contents against a lockfile (see docs/skills.md). diff --git a/package.json b/package.json index 278bee6e6c..8d18548e2b 100644 --- a/package.json +++ b/package.json @@ -192,7 +192,7 @@ }, "repository": { "type": "git", - "url": "https://github.com/Gitlawb/openclaude.git" + "url": "https://github.com/Twigpine/openclaude.git" }, "keywords": [ "claude-code", diff --git a/scripts/build.ts b/scripts/build.ts index 0e594d7d17..e522271b31 100644 --- a/scripts/build.ts +++ b/scripts/build.ts @@ -203,9 +203,9 @@ result = await Bun.build({ 'MACRO.DISPLAY_VERSION': JSON.stringify(version), 'MACRO.BUILD_TIME': JSON.stringify(new Date().toISOString()), 'MACRO.ISSUES_EXPLAINER': - JSON.stringify('report the issue at https://github.com/Gitlawb/openclaude/issues'), + JSON.stringify('report the issue at https://github.com/Twigpine/openclaude/issues'), 'MACRO.FEEDBACK_CHANNEL': - JSON.stringify('https://github.com/Gitlawb/openclaude/issues'), + JSON.stringify('https://github.com/Twigpine/openclaude/issues'), 'MACRO.PACKAGE_URL': JSON.stringify('@gitlawb/openclaude'), 'MACRO.NATIVE_PACKAGE_URL': 'undefined', 'MACRO.VERSION_CHANGELOG': 'undefined', @@ -546,9 +546,9 @@ sdkResult = await Bun.build({ 'MACRO.DISPLAY_VERSION': JSON.stringify(version), 'MACRO.BUILD_TIME': JSON.stringify(new Date().toISOString()), 'MACRO.ISSUES_EXPLAINER': - JSON.stringify('report the issue at https://github.com/Gitlawb/openclaude/issues'), + JSON.stringify('report the issue at https://github.com/Twigpine/openclaude/issues'), 'MACRO.FEEDBACK_CHANNEL': - JSON.stringify('https://github.com/Gitlawb/openclaude/issues'), + JSON.stringify('https://github.com/Twigpine/openclaude/issues'), 'MACRO.PACKAGE_URL': JSON.stringify('@gitlawb/openclaude'), 'MACRO.NATIVE_PACKAGE_URL': 'undefined', 'MACRO.VERSION_CHANGELOG': 'undefined', diff --git a/scripts/missing-module-stub.test.ts b/scripts/missing-module-stub.test.ts index 3e76f1a20e..e5f118d897 100644 --- a/scripts/missing-module-stub.test.ts +++ b/scripts/missing-module-stub.test.ts @@ -5,7 +5,7 @@ import { expect, test } from 'bun:test' const REPO_ROOT = join(import.meta.dir, '..') const DIST = join(REPO_ROOT, 'dist/cli.mjs') -// Regression for Gitlawb/openclaude#706. The bundled KAIROS dream skill +// Regression for Twigpine/openclaude#706. The bundled KAIROS dream skill // (src/skills/bundled/dream.js, not mirrored) must not stub the real // /dream slash command at src/commands/dream/dream.ts during bundling. test('/dream command is present in the CLI bundle', () => { diff --git a/src/cli/handlers/skills.test.ts b/src/cli/handlers/skills.test.ts index 7449fe7100..034764847d 100644 --- a/src/cli/handlers/skills.test.ts +++ b/src/cli/handlers/skills.test.ts @@ -570,9 +570,9 @@ test.serial('installs a registry skill by id from a local registry file', async registryPath, JSON.stringify([ buildRegistryEntry(sourceDir, { - repo: 'https://github.com/Gitlawb/openclaude-skills', + repo: 'https://github.com/Twigpine/openclaude-skills', path: 'skills/sample-skill/SKILL.md', - homepage: 'https://github.com/Gitlawb/openclaude-skills/tree/main/skills/sample-skill', + homepage: 'https://github.com/Twigpine/openclaude-skills/tree/main/skills/sample-skill', sha256: sha256OfSkillSource(VALID_SKILL), min_openclaude_version: '0.1.0', tools_required: ['Read', 'Bash'], diff --git a/src/cli/handlers/skillsInstall.ts b/src/cli/handlers/skillsInstall.ts index f5cbbce898..bd95e1e775 100644 --- a/src/cli/handlers/skillsInstall.ts +++ b/src/cli/handlers/skillsInstall.ts @@ -68,7 +68,7 @@ class RemoteSourceHttpError extends Error { } const DEFAULT_SKILLS_REGISTRY_URL = - 'https://raw.githubusercontent.com/Gitlawb/openclaude-skills/main/registry.json' + 'https://raw.githubusercontent.com/Twigpine/openclaude-skills/main/registry.json' const VALID_INSTALL_SKILL_NAME = /^[a-z0-9][a-z0-9-]*(?::[a-z0-9][a-z0-9-]*)*$/ const MAX_INSTALL_SKILL_NAME_LENGTH = 120 const REMOTE_SOURCE_TIMEOUT_MS = 30_000 diff --git a/src/commands/install-github-app/repoSlug.test.ts b/src/commands/install-github-app/repoSlug.test.ts index 79253abd66..9cd52a2612 100644 --- a/src/commands/install-github-app/repoSlug.test.ts +++ b/src/commands/install-github-app/repoSlug.test.ts @@ -4,45 +4,45 @@ import test from 'node:test' import { extractGitHubRepoSlug } from './repoSlug.ts' test('keeps owner/repo input as-is', () => { - assert.equal(extractGitHubRepoSlug('Gitlawb/openclaude'), 'Gitlawb/openclaude') + assert.equal(extractGitHubRepoSlug('Twigpine/openclaude'), 'Twigpine/openclaude') }) test('extracts slug from https GitHub URLs', () => { assert.equal( - extractGitHubRepoSlug('https://github.com/Gitlawb/openclaude'), - 'Gitlawb/openclaude', + extractGitHubRepoSlug('https://github.com/Twigpine/openclaude'), + 'Twigpine/openclaude', ) assert.equal( - extractGitHubRepoSlug('https://www.github.com/Gitlawb/openclaude.git'), - 'Gitlawb/openclaude', + extractGitHubRepoSlug('https://www.github.com/Twigpine/openclaude.git'), + 'Twigpine/openclaude', ) }) test('extracts slug from ssh GitHub URLs', () => { assert.equal( - extractGitHubRepoSlug('git@github.com:Gitlawb/openclaude.git'), - 'Gitlawb/openclaude', + extractGitHubRepoSlug('git@github.com:Twigpine/openclaude.git'), + 'Twigpine/openclaude', ) assert.equal( - extractGitHubRepoSlug('ssh://git@github.com/Gitlawb/openclaude'), - 'Gitlawb/openclaude', + extractGitHubRepoSlug('ssh://git@github.com/Twigpine/openclaude'), + 'Twigpine/openclaude', ) }) test('rejects malformed or non-GitHub URLs', () => { - assert.equal(extractGitHubRepoSlug('https://gitlab.com/Gitlawb/openclaude'), null) - assert.equal(extractGitHubRepoSlug('https://github.com/Gitlawb'), null) - assert.equal(extractGitHubRepoSlug('not actually github.com/Gitlawb/openclaude'), null) + assert.equal(extractGitHubRepoSlug('https://gitlab.com/Twigpine/openclaude'), null) + assert.equal(extractGitHubRepoSlug('https://github.com/Twigpine'), null) + assert.equal(extractGitHubRepoSlug('not actually github.com/Twigpine/openclaude'), null) assert.equal( - extractGitHubRepoSlug('https://evil.example/?next=github.com/Gitlawb/openclaude'), + extractGitHubRepoSlug('https://evil.example/?next=github.com/Twigpine/openclaude'), null, ) assert.equal( - extractGitHubRepoSlug('https://github.com.evil.example/Gitlawb/openclaude'), + extractGitHubRepoSlug('https://github.com.evil.example/Twigpine/openclaude'), null, ) assert.equal( - extractGitHubRepoSlug('https://example.com/github.com/Gitlawb/openclaude'), + extractGitHubRepoSlug('https://example.com/github.com/Twigpine/openclaude'), null, ) }) diff --git a/src/commands/model/model.test.tsx b/src/commands/model/model.test.tsx index 75abde31ee..6f0ae3b397 100644 --- a/src/commands/model/model.test.tsx +++ b/src/commands/model/model.test.tsx @@ -1017,7 +1017,7 @@ test('auto profile model picker mode uses explicit multi-model profiles as the p test('provider profile model picker surface keeps static route catalogs for single-default profiles', async () => { const activeProfile = { id: 'opengateway-profile', - name: 'Gitlawb Opengateway', + name: 'Twigpine Opengateway', provider: 'gitlawb-opengateway', baseUrl: 'https://opengateway.gitlawb.com/v1', model: 'mimo-v2.5-pro', @@ -1043,12 +1043,12 @@ test('provider profile model picker surface keeps static route catalogs for sing { value: 'mimo-v2.5-pro', label: 'MiMo v2.5 Pro', - description: 'Recommended · Provider: Gitlawb Opengateway', + description: 'Recommended · Provider: Twigpine Opengateway', }, { value: 'mimo-v2-pro', label: 'MiMo v2 Pro', - description: 'Provider: Gitlawb Opengateway', + description: 'Provider: Twigpine Opengateway', }, ], { profileModelSurface: 'provider' }, @@ -1057,12 +1057,12 @@ test('provider profile model picker surface keeps static route catalogs for sing { value: 'mimo-v2.5-pro', label: 'MiMo v2.5 Pro', - description: 'Recommended · Provider: Gitlawb Opengateway', + description: 'Recommended · Provider: Twigpine Opengateway', }, { value: 'mimo-v2-pro', label: 'MiMo v2 Pro', - description: 'Provider: Gitlawb Opengateway', + description: 'Provider: Twigpine Opengateway', }, ]) }) @@ -1549,7 +1549,7 @@ test('/model discovery override still surfaces inactive-profile switch options ( test('/model applies auto provider surface for single-model static descriptor profiles', async () => { const activeProfile = { id: 'opengateway-profile', - name: 'Gitlawb Opengateway', + name: 'Twigpine Opengateway', provider: 'gitlawb-opengateway', baseUrl: 'https://opengateway.gitlawb.com/v1', model: 'mimo-v2.5-pro', @@ -1620,7 +1620,7 @@ test('/model applies auto provider surface for single-model static descriptor pr test('/model drops expired availableUntil entries from the static picker after the cutoff', async () => { const activeProfile = { id: 'opengateway-profile', - name: 'Gitlawb Opengateway', + name: 'Twigpine Opengateway', provider: 'gitlawb-opengateway', baseUrl: 'https://opengateway.gitlawb.com/v1', model: 'mimo-v2.5-pro', @@ -1672,7 +1672,7 @@ test('/model drops expired availableUntil entries from the static picker after t test('/model merges non-empty OpenGateway discovery cache with curated entries without duplicate MiMo rows', async () => { const activeProfile = { id: 'opengateway-profile', - name: 'Gitlawb Opengateway', + name: 'Twigpine Opengateway', provider: 'gitlawb-opengateway', baseUrl: 'https://opengateway.gitlawb.com/v1', model: 'mimo-v2.5-pro', @@ -1740,7 +1740,7 @@ test('/model merges non-empty OpenGateway discovery cache with curated entries w test('/model OpenGateway interactive refresh preserves availability filter and hides expired models', async () => { const activeProfile = { id: 'opengateway-profile', - name: 'Gitlawb Opengateway', + name: 'Twigpine Opengateway', provider: 'gitlawb-opengateway', baseUrl: 'https://opengateway.gitlawb.com/v1', model: 'auto', @@ -3045,7 +3045,7 @@ test('/model refresh reports discovered model changes for dynamic active profile test('/model refresh on OpenGateway does not restore or mention expired models', async () => { const activeProfile = { id: 'opengateway-profile', - name: 'Gitlawb Opengateway', + name: 'Twigpine Opengateway', provider: 'gitlawb-opengateway', baseUrl: 'https://opengateway.gitlawb.com/v1', model: 'auto', @@ -3123,7 +3123,7 @@ test('/model refresh on OpenGateway does not restore or mention expired models', 'refresh', ) - expect(messages).toContain('Updated Gitlawb Opengateway models.') + expect(messages).toContain('Updated Twigpine Opengateway models.') expect(messages.join(' ')).not.toContain('inclusionai/ling-3.0-tiny:free') }) diff --git a/src/components/Feedback.tsx b/src/components/Feedback.tsx index 6c2d630461..ea3c107a67 100644 --- a/src/components/Feedback.tsx +++ b/src/components/Feedback.tsx @@ -36,7 +36,7 @@ import TextInput from './TextInput.js'; // This value was determined experimentally by testing the URL length limit const GITHUB_URL_LIMIT = 7250; -const GITHUB_ISSUES_REPO_URL = 'https://github.com/Gitlawb/openclaude/issues'; +const GITHUB_ISSUES_REPO_URL = 'https://github.com/Twigpine/openclaude/issues'; type Props = { abortSignal: AbortSignal; messages: Message[]; diff --git a/src/components/HelpV2/HelpV2.tsx b/src/components/HelpV2/HelpV2.tsx index 367fc397bd..80e2ee8a7d 100644 --- a/src/components/HelpV2/HelpV2.tsx +++ b/src/components/HelpV2/HelpV2.tsx @@ -149,7 +149,7 @@ export function HelpV2(t0) { } let t7; if ($[34] === Symbol.for("react.memo_cache_sentinel")) { - t7 = For more help:{" "}; + t7 = For more help:{" "}; $[34] = t7; } else { t7 = $[34]; diff --git a/src/components/ProviderManager.test.tsx b/src/components/ProviderManager.test.tsx index 7684a16a3e..bec3cce98b 100644 --- a/src/components/ProviderManager.test.tsx +++ b/src/components/ProviderManager.test.tsx @@ -123,7 +123,7 @@ async function waitForCondition( } // Provider list is sorted from generated preset metadata by description, with -// Gitlawb Opengateway pinned first, aimlapi.com second, Anthropic third, Codex OAuth injected +// Twigpine Opengateway pinned first, aimlapi.com second, Anthropic third, Codex OAuth injected // after DeepSeek, and Custom always pinned last. Keep the target-by-label // indirection here so // these tests survive future list edits without hardcoding raw key counts. @@ -131,7 +131,7 @@ async function waitForCondition( // Order matches ProviderManager.renderPresetSelection() when // canUseCodexOAuth === true (default in mocked tests). const PRESET_ORDER = [ - 'Gitlawb Opengateway', + 'Twigpine Opengateway', 'aimlapi.com', 'Anthropic', 'Alibaba Coding Plan (China)', diff --git a/src/components/StartupScreen.ts b/src/components/StartupScreen.ts index be999127d5..e6f4407b20 100644 --- a/src/components/StartupScreen.ts +++ b/src/components/StartupScreen.ts @@ -2,7 +2,7 @@ * OpenClaude startup screen — filled-block text logo with sunset gradient. * Called once at CLI startup before the Ink UI renders. * - * Addresses: https://github.com/Gitlawb/openclaude/issues/55 + * Addresses: https://github.com/Twigpine/openclaude/issues/55 */ import { isLocalProviderUrl, resolveProviderRequest } from '../services/api/providerConfig.js' diff --git a/src/components/mcp/MCPSettings.tsx b/src/components/mcp/MCPSettings.tsx index babde79150..3db630d01c 100644 --- a/src/components/mcp/MCPSettings.tsx +++ b/src/components/mcp/MCPSettings.tsx @@ -147,7 +147,7 @@ export function MCPSettings(t0: Props): React.ReactNode { return; } if (servers.length === 0 && agentMcpServers.length === 0) { - onComplete("No MCP servers configured. Please run /doctor if this is unexpected. Otherwise, run `openclaude mcp --help` or visit https://github.com/Gitlawb/openclaude to learn more."); + onComplete("No MCP servers configured. Please run /doctor if this is unexpected. Otherwise, run `openclaude mcp --help` or visit https://github.com/Twigpine/openclaude to learn more."); } }; t8 = [servers.length, filteredClients.length, agentMcpServers.length, onComplete]; diff --git a/src/constants/brand.ts b/src/constants/brand.ts index eafb00ceae..673fdcf9e5 100644 --- a/src/constants/brand.ts +++ b/src/constants/brand.ts @@ -2,7 +2,7 @@ * OpenClaude brand identity — single source of truth for the product name, * tagline, accent color, and wordmark art used across the TUI. * - * The accent is the gitlawb orange. Theme entries derived from it MUST stay + * The accent is the twigpine orange. Theme entries derived from it MUST stay * in `rgb(r,g,b)` form (never hex): the spinner's shimmer/stall interpolation * parses theme values with `parseRGB`, which only matches `rgb(...)` strings. */ @@ -11,7 +11,7 @@ export const BRAND_NAME = 'OpenClaude' export const BRAND_TAGLINE = 'Open terminal for any LLM' -/** gitlawb orange (#ff7a1a) in the rgb() form required by theme consumers. */ +/** twigpine orange (#ff7a1a) in the rgb() form required by theme consumers. */ export const BRAND_ACCENT_RGB = 'rgb(255,122,26)' /** diff --git a/src/constants/promptIdentity.test.ts b/src/constants/promptIdentity.test.ts index da8c91b5eb..8de234042e 100644 --- a/src/constants/promptIdentity.test.ts +++ b/src/constants/promptIdentity.test.ts @@ -33,7 +33,7 @@ beforeAll(async () => { DISPLAY_VERSION: '0.0.0-test', BUILD_TIME: new Date().toISOString(), ISSUES_EXPLAINER: - 'report the issue at https://github.com/Gitlawb/openclaude/issues', + 'report the issue at https://github.com/Twigpine/openclaude/issues', PACKAGE_URL: '@gitlawb/openclaude', NATIVE_PACKAGE_URL: undefined, } diff --git a/src/constants/prompts.ts b/src/constants/prompts.ts index 578e252699..959840b620 100644 --- a/src/constants/prompts.ts +++ b/src/constants/prompts.ts @@ -101,7 +101,7 @@ import type { OutputStyleConfig } from './outputStyles.js' import { CYBER_RISK_INSTRUCTION } from './cyberRiskInstruction.js' export const CLAUDE_CODE_DOCS_MAP_URL = - 'https://github.com/Gitlawb/openclaude' + 'https://github.com/Twigpine/openclaude' /** * Boundary marker separating static (cross-org cacheable) content from dynamic content. diff --git a/src/entrypoints/cli.test.ts b/src/entrypoints/cli.test.ts index 61a8a2d1fa..7570173332 100644 --- a/src/entrypoints/cli.test.ts +++ b/src/entrypoints/cli.test.ts @@ -1,6 +1,6 @@ /** * Regression tests for issue #402 — NODE_OPTIONS heap cap - * Closes: Gitlawb/openclaude#402 — JavaScript heap OOM during large tasks + * Closes: Twigpine/openclaude#402 — JavaScript heap OOM during large tasks */ import { diff --git a/src/entrypoints/sdk/stubLeakDetection.ts b/src/entrypoints/sdk/stubLeakDetection.ts index 0595858db2..aecb115b46 100644 --- a/src/entrypoints/sdk/stubLeakDetection.ts +++ b/src/entrypoints/sdk/stubLeakDetection.ts @@ -44,7 +44,7 @@ export function checkCriticalImportsForStubs( throw new Error( `SDK init error: "${name}" resolved to a build stub at runtime. ` + `This means a TUI/CLI dependency leaked into the SDK bundle. ` + - `Report this at https://github.com/Gitlawb/openclaude/issues`, + `Report this at https://github.com/Twigpine/openclaude/issues`, ) } } diff --git a/src/hooks/notifs/npmDeprecationNotification.ts b/src/hooks/notifs/npmDeprecationNotification.ts index 0972dd6340..9967b97cfd 100644 --- a/src/hooks/notifs/npmDeprecationNotification.ts +++ b/src/hooks/notifs/npmDeprecationNotification.ts @@ -5,7 +5,7 @@ import { isEnvTruthy } from 'src/utils/envUtils.js' import { hasNativeDistribution } from 'src/utils/nativeDistribution.js' const NPM_DEPRECATION_MESSAGE = - 'OpenClaude has switched from npm to the native installer. Run `openclaude install` or see https://github.com/Gitlawb/openclaude#quick-start for more options.' + 'OpenClaude has switched from npm to the native installer. Run `openclaude install` or see https://github.com/Twigpine/openclaude#quick-start for more options.' export async function getNpmDeprecationNotification(deps: { isBundledMode?: () => boolean diff --git a/src/integrations/aimlapi/config.test.ts b/src/integrations/aimlapi/config.test.ts index 6c56dc07f6..2b7dec338a 100644 --- a/src/integrations/aimlapi/config.test.ts +++ b/src/integrations/aimlapi/config.test.ts @@ -202,7 +202,7 @@ test('canonical attribution drops mixed-case managed names before restamping', ( 'x-title': 'Attacker', 'X-AIMLAPI-Source': 'agent/openclaude', 'X-AIMLAPI-Partner-ID': DEFAULT_PARTNER_ID, - 'X-AIMLAPI-Integration-Repo': 'Gitlawb/openclaude', + 'X-AIMLAPI-Integration-Repo': 'Twigpine/openclaude', 'X-AIMLAPI-Integration-Version': '1.2.3', 'HTTP-Referer': 'OpenClaude', 'X-Title': 'OpenClaude', @@ -215,7 +215,7 @@ test('canonical attribution drops mixed-case managed names before restamping', ( expectSingleManagedAttribution(resolved, { 'X-AIMLAPI-Source': 'agent/openclaude', 'X-AIMLAPI-Partner-ID': DEFAULT_PARTNER_ID, - 'X-AIMLAPI-Integration-Repo': 'Gitlawb/openclaude', + 'X-AIMLAPI-Integration-Repo': 'Twigpine/openclaude', 'X-AIMLAPI-Integration-Version': '1.2.3', 'HTTP-Referer': 'OpenClaude', 'X-Title': 'OpenClaude', diff --git a/src/integrations/aimlapi/config.ts b/src/integrations/aimlapi/config.ts index fcfddcbc03..a71b69db9d 100644 --- a/src/integrations/aimlapi/config.ts +++ b/src/integrations/aimlapi/config.ts @@ -3,7 +3,7 @@ * * Wires OpenClaude to the AI/ML API "partner checkout" flow so a user can log * in, top up their balance, and have the issued key written back into - * OpenClaude's provider profile automatically. Usage attributes to the Gitlawb + * OpenClaude's provider profile automatically. Usage attributes to the Twigpine * rebate partner (see the partner id below). * * Override any single URL via the corresponding `AIMLAPI_*_URL` env var. @@ -33,12 +33,12 @@ const DEFAULT_ENDPOINTS: AimlapiEndpoints = { /** * Partner id (`^part_[A-Za-z0-9]{1,64}$`) - rebate attribution. Must EXACTLY * match an active row in the backend `rebate_partners` table. This is the - * Gitlawb partner that all OpenClaude AI/ML API usage is credited to; it is the + * Twigpine partner that all OpenClaude AI/ML API usage is credited to; it is the * same value sent as the `X-AIMLAPI-Partner-ID` inference header (see * `integrations/gateways/aimlapi.ts`). */ export const DEFAULT_PARTNER_ID = 'part_62yQoGYDq4Yqnrj2R1iGrDNJ' -export const DEFAULT_PARTNER_NAME = 'Gitlawb' +export const DEFAULT_PARTNER_NAME = 'Twigpine' export const PARTNER_HEADER_NAME = 'X-AIMLAPI-Partner-ID' export const SOURCE_HEADER_NAME = 'X-AIMLAPI-Source' export const INTEGRATION_REPO_HEADER_NAME = 'X-AIMLAPI-Integration-Repo' diff --git a/src/integrations/aimlapi/topup.test.ts b/src/integrations/aimlapi/topup.test.ts index 7ae6dab4f6..8baaa6d174 100644 --- a/src/integrations/aimlapi/topup.test.ts +++ b/src/integrations/aimlapi/topup.test.ts @@ -671,7 +671,7 @@ test('a competing claim cannot orphan a key mint already in flight for a differe amountUsdMinor: 5000, autoTopUp: false, partnerId: 'part_test', - partnerName: 'Gitlawb', + partnerName: 'Twigpine', appBaseUrl: 'https://app.example.test', inferenceBaseUrl: 'https://api.example.test/v1', payBaseUrl: 'https://pay.example.test', @@ -1023,7 +1023,7 @@ test('CLI retains an already-exchanged checkout and blocks identical retries', a amountUsdMinor: 2500, autoTopUp: false, partnerId: 'part_62yQoGYDq4Yqnrj2R1iGrDNJ', - partnerName: 'Gitlawb', + partnerName: 'Twigpine', appBaseUrl: 'https://app.example.test', inferenceBaseUrl: 'https://api.aimlapi.com/v1', payBaseUrl: 'https://pay.example.test', @@ -1034,7 +1034,7 @@ test('CLI retains an already-exchanged checkout and blocks identical retries', a amountUsdMinor: 2500, autoTopUp: false, partnerId: 'part_62yQoGYDq4Yqnrj2R1iGrDNJ', - partnerName: 'Gitlawb', + partnerName: 'Twigpine', appBaseUrl: 'https://app.example.test', inferenceBaseUrl: 'https://api.aimlapi.com/v1', payBaseUrl: 'https://pay.example.test', @@ -1168,7 +1168,7 @@ test('a settled interrupted run resumes the profile write without re-provisionin amountUsdMinor: 2500, autoTopUp: false, partnerId: 'part_62yQoGYDq4Yqnrj2R1iGrDNJ', - partnerName: 'Gitlawb', + partnerName: 'Twigpine', appBaseUrl: 'https://app.aimlapi.com', inferenceBaseUrl: 'https://api.aimlapi.com/v1', payBaseUrl: 'https://pay.aimlapi.com', @@ -1515,7 +1515,7 @@ test('a peer settling mid-wait is resumed from instead of hard-failing the excha amountUsdMinor: 2500, autoTopUp: false, partnerId: 'part_test', - partnerName: 'Gitlawb', + partnerName: 'Twigpine', appBaseUrl: 'https://app.example.test', inferenceBaseUrl: 'https://api.example.test/v1', payBaseUrl: 'https://pay.example.test', @@ -1568,7 +1568,7 @@ test('a lease reclaimed mid-wait stops the poll instead of racing the peer to /e amountUsdMinor: 2500, autoTopUp: false, partnerId: 'part_test', - partnerName: 'Gitlawb', + partnerName: 'Twigpine', appBaseUrl: 'https://app.example.test', inferenceBaseUrl: 'https://api.example.test/v1', payBaseUrl: 'https://pay.example.test', @@ -1627,7 +1627,7 @@ test('an ambiguous exchange failure that actually committed surfaces alreadyExch amountUsdMinor: 2500, autoTopUp: false, partnerId: 'part_test', - partnerName: 'Gitlawb', + partnerName: 'Twigpine', appBaseUrl: 'https://app.example.test', inferenceBaseUrl: 'https://api.example.test/v1', payBaseUrl: 'https://pay.example.test', @@ -1688,7 +1688,7 @@ test('a caller-aborted exchange POST holds the lease instead of releasing it for amountUsdMinor: 2500, autoTopUp: false, partnerId: 'part_test', - partnerName: 'Gitlawb', + partnerName: 'Twigpine', appBaseUrl: 'https://app.example.test', inferenceBaseUrl: 'https://api.example.test/v1', payBaseUrl: 'https://pay.example.test', diff --git a/src/integrations/artifactGenerator.ts b/src/integrations/artifactGenerator.ts index 2adbd30e34..9bfcdc7e1f 100644 --- a/src/integrations/artifactGenerator.ts +++ b/src/integrations/artifactGenerator.ts @@ -234,7 +234,7 @@ function compareProviderPresetEntries( return 0 } - // Keep the primary guided providers at the top of setup: Gitlawb + // Keep the primary guided providers at the top of setup: Twigpine // Opengateway first, aimlapi.com second, then the native Anthropic option. if (leftPreset === 'gitlawb-opengateway') { return -1 diff --git a/src/integrations/discoveryService.test.ts b/src/integrations/discoveryService.test.ts index fcaa0de1ab..63ced2f630 100644 --- a/src/integrations/discoveryService.test.ts +++ b/src/integrations/discoveryService.test.ts @@ -706,7 +706,7 @@ describe('discoverModelsForRoute', () => { expect(capturedHeaders).toEqual({ 'X-AIMLAPI-Source': 'agent/openclaude', 'X-AIMLAPI-Partner-ID': 'part_62yQoGYDq4Yqnrj2R1iGrDNJ', - 'X-AIMLAPI-Integration-Repo': 'Gitlawb/openclaude', + 'X-AIMLAPI-Integration-Repo': 'Twigpine/openclaude', 'X-AIMLAPI-Integration-Version': publicBuildVersion, 'HTTP-Referer': 'OpenClaude', 'X-Title': 'OpenClaude', @@ -759,7 +759,7 @@ describe('discoverModelsForRoute', () => { expect(capturedHeaders).toEqual({ 'X-AIMLAPI-Source': 'agent/openclaude', 'X-AIMLAPI-Partner-ID': 'part_62yQoGYDq4Yqnrj2R1iGrDNJ', - 'X-AIMLAPI-Integration-Repo': 'Gitlawb/openclaude', + 'X-AIMLAPI-Integration-Repo': 'Twigpine/openclaude', 'X-AIMLAPI-Integration-Version': publicBuildVersion, 'HTTP-Referer': 'OpenClaude', 'X-Title': 'OpenClaude', @@ -803,7 +803,7 @@ describe('discoverModelsForRoute', () => { expect(headers.get('x-aimlapi-partner-id')).toBe( 'part_62yQoGYDq4Yqnrj2R1iGrDNJ', ) - expect(headers.get('x-aimlapi-integration-repo')).toBe('Gitlawb/openclaude') + expect(headers.get('x-aimlapi-integration-repo')).toBe('Twigpine/openclaude') expect(headers.get('x-aimlapi-integration-version')).toBe(publicBuildVersion) expect(headers.get('http-referer')).toBe('OpenClaude') expect(headers.get('x-title')).toBe('OpenClaude') diff --git a/src/integrations/gateways/aimlapi.ts b/src/integrations/gateways/aimlapi.ts index 059bdfad29..32b275646c 100644 --- a/src/integrations/gateways/aimlapi.ts +++ b/src/integrations/gateways/aimlapi.ts @@ -76,7 +76,7 @@ export default defineGateway({ openaiShim: { headers: withResolvedPartnerHeader({ 'X-AIMLAPI-Partner-ID': 'part_62yQoGYDq4Yqnrj2R1iGrDNJ', - 'X-AIMLAPI-Integration-Repo': 'Gitlawb/openclaude', + 'X-AIMLAPI-Integration-Repo': 'Twigpine/openclaude', 'X-AIMLAPI-Integration-Version': publicBuildVersion, // Attribution headers AI/ML API records for api.aimlapi.com requests // (issue #835). `HTTP-Referer`/`X-Title` identify the referring app. diff --git a/src/integrations/gateways/gitlawb-opengateway.ts b/src/integrations/gateways/gitlawb-opengateway.ts index 709e93f142..e2a8dac66b 100644 --- a/src/integrations/gateways/gitlawb-opengateway.ts +++ b/src/integrations/gateways/gitlawb-opengateway.ts @@ -62,7 +62,7 @@ export function mapOpenGatewayModel(raw: unknown): ModelCatalogEntry | null { export default defineGateway({ id: 'gitlawb-opengateway', - label: 'Gitlawb Opengateway', + label: 'Twigpine Opengateway', category: 'aggregating', defaultBaseUrl: 'https://opengateway.gitlawb.com/v1', defaultModel: 'mimo-v2.5-pro', @@ -80,7 +80,7 @@ export default defineGateway({ // fallbacks because existing openclaude configs may already hold generic credentials there. credentialEnvVars: ['OPENGATEWAY_API_KEY', 'OPENAI_API_KEYS', 'OPENAI_API_KEY'], missingCredentialMessage: - 'OPENGATEWAY_API_KEY is required to use Gitlawb Opengateway.\n' + + 'OPENGATEWAY_API_KEY is required to use Twigpine Opengateway.\n' + 'Mint a free API key at https://gitlawb.com/opengateway/keys and set it as OPENGATEWAY_API_KEY (or OPENAI_API_KEYS / OPENAI_API_KEY when OPENAI_BASE_URL points at opengateway).', routing: { matchBaseUrlHosts: ['opengateway.gitlawb.com', 'opengateway.fly.dev'], @@ -106,10 +106,10 @@ export default defineGateway({ }, preset: { id: 'gitlawb-opengateway', - description: 'Gitlawb Opengateway - (API key required, signup at https://gitlawb.com/opengateway/keys)', + description: 'Twigpine Opengateway - (API key required, signup at https://gitlawb.com/opengateway/keys)', apiKeyEnvVars: ['OPENGATEWAY_API_KEY'], - label: 'Gitlawb Opengateway', - name: 'Gitlawb Opengateway', + label: 'Twigpine Opengateway', + name: 'Twigpine Opengateway', badge: { text: 'Recommended', color: 'success', diff --git a/src/integrations/generated/integrationManifest.generated.ts b/src/integrations/generated/integrationManifest.generated.ts index 77b29a5b85..b57d601f2c 100644 --- a/src/integrations/generated/integrationManifest.generated.ts +++ b/src/integrations/generated/integrationManifest.generated.ts @@ -14,9 +14,9 @@ export const PROVIDER_PRESET_MANIFEST = [ "routeId": "gitlawb-opengateway", "vendorId": "openai", "gatewayId": "gitlawb-opengateway", - "description": "Gitlawb Opengateway - (API key required, signup at https://gitlawb.com/opengateway/keys)", - "label": "Gitlawb Opengateway", - "name": "Gitlawb Opengateway", + "description": "Twigpine Opengateway - (API key required, signup at https://gitlawb.com/opengateway/keys)", + "label": "Twigpine Opengateway", + "name": "Twigpine Opengateway", "apiKeyEnvVars": [ "OPENGATEWAY_API_KEY" ], diff --git a/src/screens/ResumeConversation.test.ts b/src/screens/ResumeConversation.test.ts index bae819a9e0..51c0c876e9 100644 --- a/src/screens/ResumeConversation.test.ts +++ b/src/screens/ResumeConversation.test.ts @@ -32,8 +32,8 @@ function log( test('filterResumeLogs preserves PR filters before picker grouping', () => { const prLog = log(id(1), { prNumber: 42, - prUrl: 'https://github.com/Gitlawb/openclaude/pull/42', - prRepository: 'Gitlawb/openclaude', + prUrl: 'https://github.com/Twigpine/openclaude/pull/42', + prRepository: 'Twigpine/openclaude', }) const otherPrLog = log(id(2), { prNumber: 77 }) const nonPrLog = log(id(3)) @@ -58,7 +58,7 @@ test('filterResumeLogs preserves PR filters before picker grouping', () => { expect( filterResumeLogs( [prLog, otherPrLog, nonPrLog], - 'https://github.com/Gitlawb/openclaude/pull/42', + 'https://github.com/Twigpine/openclaude/pull/42', ), ).toEqual([prLog]) expect(filterResumeLogs([prLog, sidechainLog], 42)).toEqual([prLog]) diff --git a/src/services/ads.ts b/src/services/ads.ts index 731fdbb22e..1bb189d11c 100644 --- a/src/services/ads.ts +++ b/src/services/ads.ts @@ -1,5 +1,5 @@ /** - * Client for the Gitlawb Ads service (ads.gitlawb.com). + * Client for the Twigpine Ads service (ads.gitlawb.com). * * openclaude shows opt-in "sponsored tips" during inference waits; a viewer who * dwells on one earns opengateway credits. This module is the thin HTTP client: diff --git a/src/services/api/bootstrap.test.ts b/src/services/api/bootstrap.test.ts index 21bef4be80..f5cf8bccee 100644 --- a/src/services/api/bootstrap.test.ts +++ b/src/services/api/bootstrap.test.ts @@ -220,7 +220,7 @@ test('AIMLAPI discovery passes credentials and headers on the bootstrap route', expect(fallbackOptions?.headers).toEqual({ 'X-AIMLAPI-Source': 'agent/openclaude', 'X-AIMLAPI-Partner-ID': 'part_62yQoGYDq4Yqnrj2R1iGrDNJ', - 'X-AIMLAPI-Integration-Repo': 'Gitlawb/openclaude', + 'X-AIMLAPI-Integration-Repo': 'Twigpine/openclaude', 'X-AIMLAPI-Integration-Version': publicBuildVersion, 'HTTP-Referer': 'OpenClaude', 'X-Title': 'OpenClaude', diff --git a/src/services/api/client.test.ts b/src/services/api/client.test.ts index 05428a60ee..9eea1a6bb1 100644 --- a/src/services/api/client.test.ts +++ b/src/services/api/client.test.ts @@ -1311,7 +1311,7 @@ test('routes env-only AI/ML API requests through the OpenAI-compatible shim desp ) expect(capturedHeaders?.get('x-aimlapi-partner-id')).toBe('part_62yQoGYDq4Yqnrj2R1iGrDNJ') expect(capturedHeaders?.get('x-aimlapi-integration-repo')).toBe( - 'Gitlawb/openclaude', + 'Twigpine/openclaude', ) expect(capturedHeaders?.get('x-aimlapi-integration-version')).toBe( publicBuildVersion, diff --git a/src/services/api/openaiShim/requestExecutor.integration.test.ts b/src/services/api/openaiShim/requestExecutor.integration.test.ts index 4b21e0cfb3..0ea2c25369 100644 --- a/src/services/api/openaiShim/requestExecutor.integration.test.ts +++ b/src/services/api/openaiShim/requestExecutor.integration.test.ts @@ -1083,7 +1083,7 @@ test('opengateway sends Accept-Encoding: identity header on chat requests', asyn registerGateway({ id: 'gitlawb-opengateway-test', - label: 'Gitlawb Opengateway', + label: 'Twigpine Opengateway', category: 'aggregating', defaultBaseUrl: 'https://opengateway.gitlawb.com/v1/xiaomi-mimo', defaultModel: 'mimo-v2.5-pro', @@ -2345,7 +2345,7 @@ test('gitlawb opengateway stored provider profile key becomes bearer auth', asyn applyProviderProfileToProcessEnv({ id: 'stored-opengateway', provider: 'gitlawb-opengateway', - name: 'Gitlawb Opengateway', + name: 'Twigpine Opengateway', baseUrl: 'https://opengateway.gitlawb.com/v1', model: 'mimo-v2.5-pro', apiKey: 'fake-profile-key', diff --git a/src/services/api/providerConfig.local.test.ts b/src/services/api/providerConfig.local.test.ts index fd644f84c8..bcbfd8e17e 100644 --- a/src/services/api/providerConfig.local.test.ts +++ b/src/services/api/providerConfig.local.test.ts @@ -116,7 +116,7 @@ test('keeps codex alias models on chat completions for local openai-compatible p )).toBe(true) }) -test('normalizes legacy Gitlawb Opengateway provider-prefixed base URLs to the smart route', () => { +test('normalizes legacy Twigpine Opengateway provider-prefixed base URLs to the smart route', () => { process.env.CLAUDE_CODE_USE_OPENAI = '1' process.env.OPENAI_BASE_URL = 'https://opengateway.gitlawb.com/v1/xiaomi-mimo' process.env.OPENAI_MODEL = 'zai-org/GLM-5.1-FP8' diff --git a/src/services/tips/gitlawbEarn.test.ts b/src/services/tips/gitlawbEarn.test.ts index d477676afe..bfa0f70df2 100644 --- a/src/services/tips/gitlawbEarn.test.ts +++ b/src/services/tips/gitlawbEarn.test.ts @@ -35,7 +35,7 @@ afterEach(() => { else process.env.OPENCLAUDE_ADS_TIP_EVERY = ORIGINAL_TIP_EVERY }) -describe('gitlawb earning tips', () => { +describe('twigpine earning tips', () => { test('disabled by default (no ads config)', () => { setAds(undefined) expect(adsEarningEnabled()).toBe(false) @@ -72,7 +72,7 @@ describe('gitlawb earning tips', () => { test('content falls back to a static line when the ads service is unreachable', async () => { setAds({ enabled: true, earnCode: 'earn_abc' }) const text = await buildEarningTip().content({ theme: 'dark' }) - expect(text.toLowerCase()).toContain('gitlawb.com') + expect(text.toLowerCase()).toContain('twigpine.com') }) test('content renders a fetched ad (advertiser + ad copy) on the success path', async () => { @@ -93,8 +93,8 @@ describe('gitlawb earning tips', () => { const text = await buildEarningTip().content({ theme: 'dark' }) expect(text).toContain('Serverless Postgres that scales to zero') // ad copy - expect(text).toContain('Neon') // real advertiser, not the Gitlawb fallback - expect(text.toLowerCase()).not.toContain('gitlawb.com') + expect(text).toContain('Neon') // real advertiser, not the Twigpine fallback + expect(text.toLowerCase()).not.toContain('twigpine.com') }) test('content falls back when the ad has blank copy (no blank-ad credit)', async () => { @@ -106,6 +106,6 @@ describe('gitlawb earning tips', () => { )) as typeof fetch const text = await buildEarningTip().content({ theme: 'dark' }) - expect(text.toLowerCase()).toContain('gitlawb.com') // degraded to static line + expect(text.toLowerCase()).toContain('twigpine.com') // degraded to static line }) }) diff --git a/src/services/tips/gitlawbEarn.ts b/src/services/tips/gitlawbEarn.ts index a6025c9342..c926d85646 100644 --- a/src/services/tips/gitlawbEarn.ts +++ b/src/services/tips/gitlawbEarn.ts @@ -5,14 +5,14 @@ import { renderSponsorLink } from './tipLink.js' import type { Tip, TipContext, TipSponsor } from './types.js' /** - * Gitlawb earning tips. Unlike the static partner sponsored tips (which show at + * Twigpine earning tips. Unlike the static partner sponsored tips (which show at * most once per session, gated by a per-startup counter), these target the * opt-in earning user who ran `/ads on `: they appear on a per-TURN * cadence and credit opengateway credits each time one is shown. */ -const GITLAWB: TipSponsor = { - name: 'Gitlawb', - url: 'https://gitlawb.com', +const TWIGPINE: TipSponsor = { + name: 'Twigpine', + url: 'https://twigpine.com', label: 'Sponsored', } @@ -36,7 +36,7 @@ function tipEvery(): number { let pickCounter = 0 /** - * Whether this tip slot should be a Gitlawb earning ad. Called once per turn by + * Whether this tip slot should be a Twigpine earning ad. Called once per turn by * getTipToShowOnSpinner; returns true on every Nth eligible call. Does NOT * increment (or do anything) when earning is off, so non-opted-in users and the * existing tip tests are unaffected. @@ -62,13 +62,13 @@ function renderEarningTip( const label = earning ? 'Sponsored +credits' : 'Sponsored' // Attribute to the real advertiser and point at the ad's click URL (the // partner's tracker — that's what records the click and pays us). Fall back to - // Gitlawb only for the static no-ad line. - const sponsor = ad?.name?.trim() || GITLAWB.name - // Never point a third-party advertiser's name at the Gitlawb URL: for a real + // Twigpine only for the static no-ad line. + const sponsor = ad?.name?.trim() || TWIGPINE.name + // Never point a third-party advertiser's name at the Twigpine URL: for a real // ad use only its own click URL (no link if it's missing), and reserve the - // Gitlawb fallback for the static no-ad line. + // Twigpine fallback for the static no-ad line. const adLink = ad?.link?.trim() - const linkUrl = earning ? adLink : adLink || GITLAWB.url + const linkUrl = earning ? adLink : adLink || TWIGPINE.url // Make the advertiser name a clickable hyperlink to its click URL instead of // printing the (often very long) tracker URL inline. Clicks still hit the // tracker, so attribution/payout are unchanged. @@ -78,7 +78,7 @@ function renderEarningTip( } /** - * The Gitlawb earning tip. content() fetches a real impression from the ads + * The Twigpine earning tip. content() fetches a real impression from the ads * service and schedules a confirm after the dwell so the viewer is credited for * seeing it. Any fetch/confirm failure degrades silently to a static line — ads * must never break or block the host CLI. (Confirm fires ~dwell after the tip is @@ -87,11 +87,11 @@ function renderEarningTip( export function buildEarningTip(): Tip { return { id: 'gitlawb-earn', - sponsor: GITLAWB, + sponsor: TWIGPINE, cooldownSessions: 0, isRelevant: async () => adsEarningEnabled(), content: async (ctx: TipContext) => { - const fallback = 'Earn opengateway credits while you code — gitlawb.com' + const fallback = 'Earn opengateway credits while you code — twigpine.com' const code = getGlobalConfig().ads?.earnCode if (!code) return renderEarningTip(fallback, ctx, false) diff --git a/src/services/tips/tipScheduler.test.ts b/src/services/tips/tipScheduler.test.ts index 80d7d50df3..f7c7d53711 100644 --- a/src/services/tips/tipScheduler.test.ts +++ b/src/services/tips/tipScheduler.test.ts @@ -168,7 +168,7 @@ describe('getTipToShowOnSpinner — sponsored partitioning', () => { }) describe('getTipToShowOnSpinner — earning branch', () => { - test('returns the Gitlawb earning tip when earning is enabled', async () => { + test('returns the Twigpine earning tip when earning is enabled', async () => { setState({ numStartups: 100, lastSponsored: 80, // would otherwise be an eligible sponsored slot diff --git a/src/services/tips/tipScheduler.ts b/src/services/tips/tipScheduler.ts index 95ec776851..7f055edb56 100644 --- a/src/services/tips/tipScheduler.ts +++ b/src/services/tips/tipScheduler.ts @@ -55,7 +55,7 @@ export async function getTipToShowOnSpinner( return undefined } - // Opt-in earning users (`/ads on `) see Gitlawb sponsored tips on a + // Opt-in earning users (`/ads on `) see Twigpine sponsored tips on a // per-turn cadence, bypassing the per-startup sponsored gate — they opted in // to earn, so we surface (and credit) ads frequently rather than once a session. if (shouldShowEarningTip()) { diff --git a/src/services/tips/types.ts b/src/services/tips/types.ts index 1f2c3deef1..4a33b62e93 100644 --- a/src/services/tips/types.ts +++ b/src/services/tips/types.ts @@ -6,7 +6,7 @@ export type TipContext = { readFileState?: FileStateCache bashTools?: Set /** - * The viewer's latest prompt text, used ONLY by the opt-in Gitlawb earning + * The viewer's latest prompt text, used ONLY by the opt-in Twigpine earning * tip to fetch a contextually-matched sponsored ad. Sent to the ads partner * only when sponsored tips are enabled (which discloses this sharing), and * sanitized at the client boundary before it leaves the process. diff --git a/src/tools/WebSearchTool/providers/custom.ts b/src/tools/WebSearchTool/providers/custom.ts index db3622ddbb..dd93cce3db 100644 --- a/src/tools/WebSearchTool/providers/custom.ts +++ b/src/tools/WebSearchTool/providers/custom.ts @@ -403,7 +403,7 @@ function auditLogCustomSearch(url: string): void { `[web-search] ⚠️ Custom search provider is active. ` + `Outbound requests go to: ${safeHostname(url) ?? url}. ` + `Ensure this endpoint is trusted. ` + - `See: https://github.com/Gitlawb/openclaude/pull/512#security`, + `See: https://github.com/Twigpine/openclaude/pull/512#security`, ) } diff --git a/src/utils/attribution.test.ts b/src/utils/attribution.test.ts index 136e543421..edfcb8dc7e 100644 --- a/src/utils/attribution.test.ts +++ b/src/utils/attribution.test.ts @@ -72,7 +72,7 @@ const originalClientType = getClientType() const originalMainLoopModelOverride = getMainLoopModelOverride() const defaultPrAttribution = - '🤖 Generated with [OpenClaude](https://github.com/Gitlawb/openclaude)' + '🤖 Generated with [OpenClaude](https://github.com/Twigpine/openclaude)' function useSettings(settings: SettingsJson): void { testSettings = settings diff --git a/src/utils/attribution.ts b/src/utils/attribution.ts index e7c3ed928f..6e637d862e 100644 --- a/src/utils/attribution.ts +++ b/src/utils/attribution.ts @@ -45,7 +45,7 @@ export type AttributionTexts = { } const DEFAULT_PR_ATTRIBUTION = - '🤖 Generated with [OpenClaude](https://github.com/Gitlawb/openclaude)' + '🤖 Generated with [OpenClaude](https://github.com/Twigpine/openclaude)' function sanitizeCoAuthorNamePart(value: string): string { return value @@ -458,7 +458,7 @@ export async function getEnhancedPRAttribution( memoryAccessCount > 0 ? `, ${memoryAccessCount} ${memoryAccessCount === 1 ? 'memory' : 'memories'} recalled` : '' - const summary = `🤖 Generated with [OpenClaude](https://github.com/Gitlawb/openclaude) (${claudePercent}% ${promptCount}-shotted by ${shortModelName}${memSuffix})` + const summary = `🤖 Generated with [OpenClaude](https://github.com/Twigpine/openclaude) (${claudePercent}% ${promptCount}-shotted by ${shortModelName}${memSuffix})` // Append trailer lines for squash-merge survival. Only for allowlisted repos // (INTERNAL_MODEL_REPOS) and only in builds with COMMIT_ATTRIBUTION enabled — diff --git a/src/utils/conversationRecovery.test.ts b/src/utils/conversationRecovery.test.ts index 58fddbc7e7..c20a956fb4 100644 --- a/src/utils/conversationRecovery.test.ts +++ b/src/utils/conversationRecovery.test.ts @@ -262,8 +262,8 @@ test('findResumeLogByPrSelector selects the first non-sidechain PR match', async isSidechain: false, sessionId: id(12), prNumber: 1642, - prUrl: 'https://github.com/Gitlawb/openclaude/pull/1642', - prRepository: 'Gitlawb/openclaude', + prUrl: 'https://github.com/Twigpine/openclaude/pull/1642', + prRepository: 'Twigpine/openclaude', } as any const sidechain = { ...linked, @@ -274,7 +274,7 @@ test('findResumeLogByPrSelector selects the first non-sidechain PR match', async ...linked, sessionId: id(14), prNumber: 17, - prUrl: 'https://github.com/Gitlawb/openclaude/pull/17', + prUrl: 'https://github.com/Twigpine/openclaude/pull/17', } as any expect(findResumeLogByPrSelector([sidechain, linked, unrelated], true)).toBe( @@ -286,7 +286,7 @@ test('findResumeLogByPrSelector selects the first non-sidechain PR match', async expect( findResumeLogByPrSelector( [sidechain, linked, unrelated], - 'https://github.com/Gitlawb/openclaude/pull/1642', + 'https://github.com/Twigpine/openclaude/pull/1642', ), ).toBe(linked) expect( diff --git a/src/utils/http.test.ts b/src/utils/http.test.ts index 97bc12cadc..c1d910b98b 100644 --- a/src/utils/http.test.ts +++ b/src/utils/http.test.ts @@ -38,7 +38,7 @@ test('WebFetch identifies a custom Anthropic endpoint as third-party', () => { process.env.ANTHROPIC_BASE_URL = 'https://proxy.example/v1' expect(getWebFetchUserAgent()).toContain( - '+https://github.com/Gitlawb/openclaude', + '+https://github.com/Twigpine/openclaude', ) }) diff --git a/src/utils/http.ts b/src/utils/http.ts index 6536cb2b5e..5effb54d65 100644 --- a/src/utils/http.ts +++ b/src/utils/http.ts @@ -58,7 +58,7 @@ export function getWebFetchUserAgent(): string { const supportUrl = isFirstPartyAnthropicProvider() ? 'https://support.anthropic.com/' - : 'https://github.com/Gitlawb/openclaude' + : 'https://github.com/Twigpine/openclaude' return `Claude-User (${getClaudeCodeUserAgent()}; +${supportUrl})` } diff --git a/src/utils/model/routeCatalogOptions.test.ts b/src/utils/model/routeCatalogOptions.test.ts index 8598968766..2719dbf9db 100644 --- a/src/utils/model/routeCatalogOptions.test.ts +++ b/src/utils/model/routeCatalogOptions.test.ts @@ -42,7 +42,7 @@ describe('buildRouteCatalogModelOptions', () => { }) test('surfaces catalog entry notes as a description tag', () => { - const options = buildRouteCatalogModelOptions('Gitlawb Opengateway', [ + const options = buildRouteCatalogModelOptions('Twigpine Opengateway', [ { id: 'opengateway-nemotron-3-ultra-free', apiName: 'nvidia/nemotron-3-ultra-550b-a55b:free', @@ -51,7 +51,7 @@ describe('buildRouteCatalogModelOptions', () => { }, ]) - expect(options[0]?.description).toBe('Free · Provider: Gitlawb Opengateway') + expect(options[0]?.description).toBe('Free · Provider: Twigpine Opengateway') }) }) diff --git a/src/utils/providerAutoDetect.ts b/src/utils/providerAutoDetect.ts index 65a955e62e..e6dd8d8543 100644 --- a/src/utils/providerAutoDetect.ts +++ b/src/utils/providerAutoDetect.ts @@ -338,7 +338,7 @@ function normalizeOpengatewayBaseUrl(baseUrl: string): string { } /** - * Fallback: the Gitlawb Opengateway exposes partner inference through a + * Fallback: the Twigpine Opengateway exposes partner inference through a * smart OpenAI-compatible route. As of 2026-05-22 it requires a per-user API * key (signup at https://gitlawb.com/opengateway/keys); without a key we return * null so the caller surfaces the missing-credential prompt instead of @@ -356,7 +356,7 @@ function defaultOpengatewayProvider(env: EnvLike): DetectedProvider | null { return { kind: 'gitlawb-opengateway', source: - 'Gitlawb Opengateway (API key required, signup at https://gitlawb.com/opengateway/keys)', + 'Twigpine Opengateway (API key required, signup at https://gitlawb.com/opengateway/keys)', baseUrl: normalizeOpengatewayBaseUrl(baseUrl), model: OPENGATEWAY_DEFAULT_MODEL, } @@ -371,7 +371,7 @@ export async function detectBestProvider(options?: { /** Override for Codex auth-file detection. See detectProviderFromEnv. */ hasCodexAuth?: () => boolean /** - * Disable the Gitlawb Opengateway fallback. Returns null when no other + * Disable the Twigpine Opengateway fallback. Returns null when no other * provider is detected. Use this in tests that need to assert "nothing found". */ skipOpengatewayFallback?: boolean diff --git a/src/utils/providerProfile.test.ts b/src/utils/providerProfile.test.ts index 21fb146c84..cfe14e1e31 100644 --- a/src/utils/providerProfile.test.ts +++ b/src/utils/providerProfile.test.ts @@ -980,7 +980,7 @@ test('openai launch ignores codex persisted transport hints', async () => { assert.equal(env.OPENAI_API_KEY, 'sk-live') }) -test('buildStartupEnvFromProfile defaults fresh installs to Gitlawb Opengateway', async () => { +test('buildStartupEnvFromProfile defaults fresh installs to Twigpine Opengateway', async () => { const env = await buildStartupEnvFromProfile({ persisted: null, processEnv: {}, @@ -1321,13 +1321,13 @@ test('buildStartupEnvFromProfile preserves env-only Fireworks setup without a sa }, }) - // Must NOT fall through to Gitlawb Opengateway default + // Must NOT fall through to Twigpine Opengateway default assert.equal(env.FIREWORKS_API_KEY, 'fw-key') assert.equal(env.CLAUDE_CODE_USE_OPENAI, undefined) assert.equal( env.OPENAI_BASE_URL, undefined, - 'should not inject Gitlawb Opengateway base URL', + 'should not inject Twigpine Opengateway base URL', ) assert.equal(isDefaultStartupProviderEnv(env), false) }) @@ -1344,7 +1344,7 @@ test('buildStartupEnvFromProfile preserves env-only NEAR AI setup without a save assert.equal( env.OPENAI_BASE_URL, undefined, - 'should not inject Gitlawb Opengateway base URL', + 'should not inject Twigpine Opengateway base URL', ) assert.equal(isDefaultStartupProviderEnv(env), false) }) @@ -1361,7 +1361,7 @@ test('buildStartupEnvFromProfile preserves env-only LongCat setup without a save assert.equal( env.OPENAI_BASE_URL, undefined, - 'should not inject Gitlawb Opengateway base URL', + 'should not inject Twigpine Opengateway base URL', ) assert.equal(isDefaultStartupProviderEnv(env), false) }) diff --git a/src/utils/providerProfile.ts b/src/utils/providerProfile.ts index c47c52a6c6..8c50405667 100644 --- a/src/utils/providerProfile.ts +++ b/src/utils/providerProfile.ts @@ -2550,7 +2550,7 @@ export async function buildStartupEnvFromProfile(options?: { return processEnv } - // No saved profile — default to Gitlawb Opengateway. + // No saved profile — default to Twigpine Opengateway. const env = buildCompatibilityProcessEnv({ processEnv, compatibilityMode: 'openai', diff --git a/src/utils/providerProfiles.test.ts b/src/utils/providerProfiles.test.ts index 9af2872db8..0658e056e9 100644 --- a/src/utils/providerProfiles.test.ts +++ b/src/utils/providerProfiles.test.ts @@ -3367,7 +3367,7 @@ describe('applyActiveProviderProfileFromConfig', () => { // user on built-in Anthropic. Previously applyActiveProviderProfileFromConfig() // returned without marking provider env as handled (the sentinel resolves to // no profile), so buildStartupEnvFromProfile() saw the missing mirror as a - // fresh install and synthesized the default Gitlawb OpenGateway env — + // fresh install and synthesized the default Twigpine OpenGateway env — // silently moving the user back onto a third-party provider. const { applyActiveProviderProfileFromConfig, ANTHROPIC_DEFAULT_PROFILE_ID } = await importFreshProviderProfileModules() diff --git a/src/utils/providerProfiles.ts b/src/utils/providerProfiles.ts index 63c1f815b1..baf2c2e113 100644 --- a/src/utils/providerProfiles.ts +++ b/src/utils/providerProfiles.ts @@ -1393,7 +1393,7 @@ export function applyActiveProviderProfileFromConfig( // to undefined, so without this guard we would return below without marking // provider env as handled; buildStartupEnvFromProfile() then treats the // profile mirror that clearActiveProviderProfile() deleted as a fresh install - // and synthesizes the default Gitlawb OpenGateway env, bouncing the user off + // and synthesizes the default Twigpine OpenGateway env, bouncing the user off // built-in Anthropic on the next launch (#1429). Clear any managed provider // env and set the applied flag so the legacy/fresh-install fallback is // suppressed. An explicit startup provider selection still wins for the diff --git a/src/utils/releaseNotes.test.ts b/src/utils/releaseNotes.test.ts index 162462406b..6f4e92d081 100644 --- a/src/utils/releaseNotes.test.ts +++ b/src/utils/releaseNotes.test.ts @@ -57,13 +57,13 @@ test('getRecentReleaseNotes treats legacy internal seen versions as unseen', () test('release-please changelog headings are normalized for version lookups', () => { const changelog = `# Changelog -## [0.8.0](https://github.com/Gitlawb/openclaude/compare/v0.7.0...v0.8.0) (2026-05-02) +## [0.8.0](https://github.com/Twigpine/openclaude/compare/v0.7.0...v0.8.0) (2026-05-02) ### Features * add thing -## [0.7.0](https://github.com/Gitlawb/openclaude/compare/v0.6.0...v0.7.0) (2026-04-26) +## [0.7.0](https://github.com/Twigpine/openclaude/compare/v0.6.0...v0.7.0) (2026-04-26) ### Bug Fixes @@ -77,7 +77,7 @@ test('release-please changelog headings are normalized for version lookups', () test('getReleaseTagUrl normalizes build metadata to the public tag', () => { expect(getReleaseTagUrl('0.8.0+abc123')).toBe( - 'https://github.com/Gitlawb/openclaude/releases/tag/v0.8.0', + 'https://github.com/Twigpine/openclaude/releases/tag/v0.8.0', ) }) diff --git a/src/utils/releaseNotes.ts b/src/utils/releaseNotes.ts index 8b66f3b47e..a22809bc10 100644 --- a/src/utils/releaseNotes.ts +++ b/src/utils/releaseNotes.ts @@ -17,7 +17,7 @@ import { const MAX_RELEASE_NOTES_SHOWN = 5 const RELEASES_API_URL = - 'https://api.github.com/repos/Gitlawb/openclaude/releases?per_page=10' + 'https://api.github.com/repos/Twigpine/openclaude/releases?per_page=10' const SECTION_HEADER_PREFIX = '__section__:' type GitHubRelease = { diff --git a/src/utils/reportTask.test.ts b/src/utils/reportTask.test.ts index 07646ead9e..68c2c5a18f 100644 --- a/src/utils/reportTask.test.ts +++ b/src/utils/reportTask.test.ts @@ -925,13 +925,13 @@ describe('task report generation', () => { type: 'pr-link', sessionId, prNumber: 456, - prUrl: 'https://github.com/Gitlawb/openclaude/pull/456', - prRepository: 'Gitlawb/openclaude', + prUrl: 'https://github.com/Twigpine/openclaude/pull/456', + prRepository: 'Twigpine/openclaude', timestamp: '2026-06-27T08:01:00.000Z', }, userMessage( '00000000-0000-4000-8000-000000000008', - 'Update src/report.ts for https://github.com/Gitlawb/openclaude/issues/123.', + 'Update src/report.ts for https://github.com/Twigpine/openclaude/issues/123.', '2026-06-27T08:00:00.000Z', ), assistantToolMessage( @@ -975,8 +975,8 @@ describe('task report generation', () => { ) expect(report.branch.pullRequest).toEqual({ number: 456, - repository: 'Gitlawb/openclaude', - url: 'https://github.com/Gitlawb/openclaude/pull/456', + repository: 'Twigpine/openclaude', + url: 'https://github.com/Twigpine/openclaude/pull/456', }) expect(report.git).toEqual( expect.objectContaining({ @@ -995,14 +995,14 @@ describe('task report generation', () => { { kind: 'issue', number: 123, - repository: 'Gitlawb/openclaude', - url: 'https://github.com/Gitlawb/openclaude/issues/123', + repository: 'Twigpine/openclaude', + url: 'https://github.com/Twigpine/openclaude/issues/123', }, { kind: 'pull_request', number: 456, - repository: 'Gitlawb/openclaude', - url: 'https://github.com/Gitlawb/openclaude/pull/456', + repository: 'Twigpine/openclaude', + url: 'https://github.com/Twigpine/openclaude/pull/456', }, ]) }, @@ -1219,7 +1219,7 @@ describe('task report generation', () => { toolResultMessage( '00000000-0000-4000-8000-000000000023', 'tool-read', - 'File body mentions https://github.com/Gitlawb/openclaude/issues/999.', + 'File body mentions https://github.com/Twigpine/openclaude/issues/999.', '2026-06-27T08:01:01.000Z', ), ], @@ -1770,13 +1770,13 @@ describe('task report generation', () => { type: 'pr-link', sessionId, prNumber: 456, - prUrl: 'https://github.com/Gitlawb/openclaude/pull/456', - prRepository: 'Gitlawb/openclaude', + prUrl: 'https://github.com/Twigpine/openclaude/pull/456', + prRepository: 'Twigpine/openclaude', timestamp: '2026-06-27T08:01:00.000Z', }, userMessage( '00000000-0000-4000-8000-000000000103', - 'Update src/report.ts for https://github.com/Gitlawb/openclaude/issues/123.', + 'Update src/report.ts for https://github.com/Twigpine/openclaude/issues/123.', '2026-06-27T08:00:00.000Z', reportCwd, ), @@ -1820,12 +1820,12 @@ describe('task report generation', () => { '- Worktree branch: `feat/session-task-report-json`', ) expect(markdown).toContain( - '- Pull request: [#456]() (`Gitlawb/openclaude`)', + '- Pull request: [#456]() (`Twigpine/openclaude`)', ) expect(markdown).toContain(`- \`${reportSourcePath}\` (git, tool)`) expect(markdown).toContain(`- \`${reportTestPath}\` (git)`) expect(markdown).toContain( - '- pull_request: [#456]() (`Gitlawb/openclaude`)', + '- pull_request: [#456]() (`Twigpine/openclaude`)', ) }, ) @@ -1849,8 +1849,8 @@ describe('task report generation', () => { { kind: 'issue', number: 321, - repository: 'Gitlawb/openclaude', - url: 'https://github.com/Gitlawb/openclaude/issues/321?label=a(b)', + repository: 'Twigpine/openclaude', + url: 'https://github.com/Twigpine/openclaude/issues/321?label=a(b)', }, { kind: 'pull_request', @@ -1862,7 +1862,7 @@ describe('task report generation', () => { const markdown = formatTaskReportAsMarkdown(report) expect(markdown).toContain( - '- issue: [#321]() (`Gitlawb/openclaude`)', + '- issue: [#321]() (`Twigpine/openclaude`)', ) expect(markdown).toContain('- pull_request: `#9`') expect(markdown).not.toContain('javascript:alert') diff --git a/src/utils/theme.ts b/src/utils/theme.ts index 23a09a51d6..28b3a00bb9 100644 --- a/src/utils/theme.ts +++ b/src/utils/theme.ts @@ -6,7 +6,7 @@ export type Theme = { bashBorder: string claude: string claudeShimmer: string // Lighter version of claude color for shimmer effect - // OpenClaude brand accent (gitlawb orange). Values MUST be rgb() strings in + // OpenClaude brand accent (twigpine orange). Values MUST be rgb() strings in // truecolor themes — spinner shimmer/stall interpolation parses them with // parseRGB, which silently fails on hex. brand: string diff --git a/src/utils/version.ts b/src/utils/version.ts index 9691c1efdf..7cc5b2ba7f 100644 --- a/src/utils/version.ts +++ b/src/utils/version.ts @@ -4,7 +4,7 @@ import { fileURLToPath } from 'url' import { coerce } from 'semver' export const OPENCLAUDE_RELEASES_URL = - 'https://github.com/Gitlawb/openclaude/releases' + 'https://github.com/Twigpine/openclaude/releases' export function normalizePublicVersion(version: string): string { const trimmedVersion = version.trim() diff --git a/vscode-extension/openclaude-vscode/package.json b/vscode-extension/openclaude-vscode/package.json index 79194cfdce..2c99cbc835 100644 --- a/vscode-extension/openclaude-vscode/package.json +++ b/vscode-extension/openclaude-vscode/package.json @@ -229,7 +229,7 @@ ], "repository": { "type": "git", - "url": "https://github.com/Gitlawb/openclaude" + "url": "https://github.com/Twigpine/openclaude" }, "license": "MIT" } diff --git a/vscode-extension/openclaude-vscode/src/extension.js b/vscode-extension/openclaude-vscode/src/extension.js index 18243e7a39..b3b9cc3d2b 100644 --- a/vscode-extension/openclaude-vscode/src/extension.js +++ b/vscode-extension/openclaude-vscode/src/extension.js @@ -16,8 +16,8 @@ const { ChatController, OpenClaudeChatViewProvider, OpenClaudeChatPanelManager } const { SessionManager } = require('./chat/sessionManager'); const { DiffContentProvider, SCHEME: DIFF_SCHEME } = require('./chat/diffController'); -const OPENCLAUDE_REPO_URL = 'https://github.com/Gitlawb/openclaude'; -const OPENCLAUDE_SETUP_URL = 'https://github.com/Gitlawb/openclaude/blob/main/README.md#quick-start'; +const OPENCLAUDE_REPO_URL = 'https://github.com/Twigpine/openclaude'; +const OPENCLAUDE_SETUP_URL = 'https://github.com/Twigpine/openclaude/blob/main/README.md#quick-start'; const PROFILE_FILE_NAME = '.openclaude-profile.json'; const SECRET_AZURE_API_KEY = 'openclaude.azure.apiKey'; diff --git a/web/astro.config.mjs b/web/astro.config.mjs index caf404bad3..f8e1a83145 100644 --- a/web/astro.config.mjs +++ b/web/astro.config.mjs @@ -5,7 +5,7 @@ export default defineConfig({ site: 'https://openclaude.gitlawb.com', trailingSlash: 'always', redirects: { - '/changelog/': 'https://github.com/Gitlawb/openclaude/releases', + '/changelog/': 'https://github.com/Twigpine/openclaude/releases', }, integrations: [sitemap()], }) diff --git a/web/public/llms.txt b/web/public/llms.txt index b74c2dfd68..5f0e6e50ae 100644 --- a/web/public/llms.txt +++ b/web/public/llms.txt @@ -6,33 +6,33 @@ OpenClaude originated from the Claude Code codebase and has since been substanti ## Project -- [GitHub repository](https://github.com/Gitlawb/openclaude): source code, releases, and issue tracker +- [GitHub repository](https://github.com/Twigpine/openclaude): source code, releases, and issue tracker - [npm package](https://www.npmjs.com/package/@gitlawb/openclaude): `@gitlawb/openclaude` -- [GitLawb mirror](https://gitlawb.com/node/repos/z6MkqDnb/openclaude) -- [Security policy](https://github.com/Gitlawb/openclaude/security/policy) -- [License notice](https://github.com/Gitlawb/openclaude/blob/main/LICENSE): MIT applies only to OpenClaude contributors' modifications; the underlying Claude Code code is Anthropic's proprietary software. +- [Twigpine mirror](https://gitlawb.com/node/repos/z6MkqDnb/openclaude) +- [Security policy](https://github.com/Twigpine/openclaude/security/policy) +- [License notice](https://github.com/Twigpine/openclaude/blob/main/LICENSE): MIT applies only to OpenClaude contributors' modifications; the underlying Claude Code code is Anthropic's proprietary software. ## Install -- [Quick start (Mac/Linux)](https://github.com/Gitlawb/openclaude/blob/main/docs/quick-start-mac-linux.md) -- [Quick start (Windows)](https://github.com/Gitlawb/openclaude/blob/main/docs/quick-start-windows.md) -- [Non-technical setup](https://github.com/Gitlawb/openclaude/blob/main/docs/non-technical-setup.md) -- [Android install](https://github.com/Gitlawb/openclaude/blob/main/ANDROID_INSTALL.md) +- [Quick start (Mac/Linux)](https://github.com/Twigpine/openclaude/blob/main/docs/quick-start-mac-linux.md) +- [Quick start (Windows)](https://github.com/Twigpine/openclaude/blob/main/docs/quick-start-windows.md) +- [Non-technical setup](https://github.com/Twigpine/openclaude/blob/main/docs/non-technical-setup.md) +- [Android install](https://github.com/Twigpine/openclaude/blob/main/ANDROID_INSTALL.md) - [npm install](https://www.npmjs.com/package/@gitlawb/openclaude): `npm install -g @gitlawb/openclaude@latest` (requires Node >= 22) - [AUR package: openclaude](https://aur.archlinux.org/packages/openclaude) ## Documentation -- [README](https://github.com/Gitlawb/openclaude/blob/main/README.md): overview, supported providers, features -- [Advanced setup](https://github.com/Gitlawb/openclaude/blob/main/docs/advanced-setup.md) -- [Smart routing](https://github.com/Gitlawb/openclaude/blob/main/docs/smart-routing.md) -- [Agent routing](https://github.com/Gitlawb/openclaude/blob/main/docs/agent-routing.md) -- [Headless gRPC server](https://github.com/Gitlawb/openclaude/blob/main/docs/grpc-server.md) -- [Repository map](https://github.com/Gitlawb/openclaude/blob/main/docs/repo-map.md) -- [VS Code extension](https://github.com/Gitlawb/openclaude/blob/main/vscode-extension/openclaude-vscode/README.md) +- [README](https://github.com/Twigpine/openclaude/blob/main/README.md): overview, supported providers, features +- [Advanced setup](https://github.com/Twigpine/openclaude/blob/main/docs/advanced-setup.md) +- [Smart routing](https://github.com/Twigpine/openclaude/blob/main/docs/smart-routing.md) +- [Agent routing](https://github.com/Twigpine/openclaude/blob/main/docs/agent-routing.md) +- [Headless gRPC server](https://github.com/Twigpine/openclaude/blob/main/docs/grpc-server.md) +- [Repository map](https://github.com/Twigpine/openclaude/blob/main/docs/repo-map.md) +- [VS Code extension](https://github.com/Twigpine/openclaude/blob/main/vscode-extension/openclaude-vscode/README.md) ## Community - [Discord](https://discord.gg/k68zFR6AcB) -- [GitHub Discussions](https://github.com/Gitlawb/openclaude/discussions) +- [GitHub Discussions](https://github.com/Twigpine/openclaude/discussions) - [X / Twitter](https://x.com/gitlawb) \ No newline at end of file diff --git a/web/public/partners/gitlawb.png b/web/public/partners/twigpine.png similarity index 100% rename from web/public/partners/gitlawb.png rename to web/public/partners/twigpine.png diff --git a/web/src/components/Footer.astro b/web/src/components/Footer.astro index 0d2c7ebee6..c86ef40c7e 100644 --- a/web/src/components/Footer.astro +++ b/web/src/components/Footer.astro @@ -34,12 +34,12 @@ const columns = [ ], }, { - title: 'gitlawb', + title: 'Twigpine', links: [ - { href: SITE.gitlawb, label: 'gitlawb.com' }, + { href: SITE.twigpine, label: 'twigpine.com' }, { href: SITE.gitlawbRepo, label: 'repo mirror' }, - { href: `${SITE.gitlawb}/architecture`, label: 'architecture' }, - { href: `${SITE.gitlawb}/agents`, label: 'agents' }, + { href: `${SITE.twigpine}/architecture`, label: 'architecture' }, + { href: `${SITE.twigpine}/agents`, label: 'agents' }, ], }, ] @@ -67,7 +67,7 @@ const columns = [ openclaude · - open source coding agent, aligned with gitlawb + open source coding agent, aligned with Twigpine · runs anywhere. uses anything. diff --git a/web/src/components/Nav.astro b/web/src/components/Nav.astro index 0184e67cfa..1ee267125d 100644 --- a/web/src/components/Nav.astro +++ b/web/src/components/Nav.astro @@ -7,7 +7,7 @@ const links = [ { href: '/buddy/', label: 'buddy' }, { href: SITE.releasesUrl, label: "what's new", newTab: true }, { href: SITE.github, label: 'github' }, - { href: SITE.gitlawb, label: 'gitlawb' }, + { href: SITE.twigpine, label: 'twigpine' }, ] const path = Astro.url.pathname diff --git a/web/src/data/configuration.ts b/web/src/data/configuration.ts index 59c059e8fb..d0a901a024 100644 --- a/web/src/data/configuration.ts +++ b/web/src/data/configuration.ts @@ -72,7 +72,7 @@ export const envVars: EnvVar[] = [ { name: 'OPENAI_API_KEYS', description: 'Comma-separated key pool for OpenAI-compatible endpoints; rotates on failure and is checked before OPENAI_API_KEY.' }, { name: 'OPENAI_BASE_URL', description: 'Base URL of an OpenAI-compatible /v1 endpoint (OpenRouter, LM Studio, LiteLLM, …).' }, { name: 'OPENAI_MODEL', description: 'Model name to request from the OpenAI-compatible endpoint.' }, - { name: 'OPENGATEWAY_API_KEY', description: 'Gitlawb Opengateway key (preferred over OPENAI_API_KEY for the gateway).' }, + { name: 'OPENGATEWAY_API_KEY', description: 'Twigpine Opengateway key (preferred over OPENAI_API_KEY for the gateway).' }, { name: 'OPENGATEWAY_BASE_URL', description: 'Override the Opengateway base URL.' }, { name: 'CLAUDE_CODE_OPENAI_CONTEXT_WINDOWS', description: 'JSON map of model → context window; takes precedence over settings.modelLimits.' }, { name: 'CLAUDE_CODE_OPENAI_MAX_OUTPUT_TOKENS', description: 'JSON map of model → max output tokens; takes precedence over settings.modelLimits.' }, diff --git a/web/src/data/partners.ts b/web/src/data/partners.ts index 6dcba990f6..55bb9ba22a 100644 --- a/web/src/data/partners.ts +++ b/web/src/data/partners.ts @@ -12,7 +12,7 @@ export interface Partner { } export const partners: Partner[] = [ - { name: 'GitLawb', url: 'https://gitlawb.com', logo: '/partners/gitlawb.png', height: 44 }, + { name: 'Twigpine', url: 'https://twigpine.com', logo: '/partners/twigpine.png', height: 44 }, { name: 'Bankr.bot', url: 'https://bankr.bot', logo: '/partners/bankr.svg', height: 40 }, { name: 'Atomic Chat', url: 'https://atomic.chat/', logo: '/partners/atomic-chat-logo.png', height: 40 }, { name: 'Xiaomi MiMo', url: 'https://mimo.mi.com', logo: '/partners/mimo.svg', height: 30 }, @@ -55,9 +55,9 @@ export const partners: Partner[] = [ ] export const community = [ - { name: 'github', url: 'https://github.com/Gitlawb/openclaude', label: 'star the repo' }, + { name: 'github', url: 'https://github.com/Twigpine/openclaude', label: 'star the repo' }, { name: 'discord', url: 'https://discord.gg/k68zFR6AcB', label: 'join the discord' }, { name: 'x', url: 'https://x.com/gitlawb', label: 'follow @gitlawb' }, - { name: 'discussions', url: 'https://github.com/Gitlawb/openclaude/discussions', label: 'open a discussion' }, + { name: 'discussions', url: 'https://github.com/Twigpine/openclaude/discussions', label: 'open a discussion' }, { name: 'trendshift', url: 'https://trendshift.io/repositories/25807', label: 'featured on trendshift' }, ] diff --git a/web/src/data/providers.ts b/web/src/data/providers.ts index 44e46e6ffe..a6dab0016c 100644 --- a/web/src/data/providers.ts +++ b/web/src/data/providers.ts @@ -116,7 +116,7 @@ export const providers: Provider[] = [ // ── gateways ───────────────────────────────────────────────────────── { id: 'opengateway', - name: 'Gitlawb Opengateway', + name: 'Twigpine Opengateway', group: 'gateways', setup: 'startup default, /provider, or env vars', envVars: ['OPENGATEWAY_API_KEY'], diff --git a/web/src/data/site.ts b/web/src/data/site.ts index 944b3323f1..b70b76a0b8 100644 --- a/web/src/data/site.ts +++ b/web/src/data/site.ts @@ -6,9 +6,13 @@ export const SITE = { 'Open-source coding agent that runs in your terminal and talks to any model: OpenAI, Gemini, Ollama, GitHub Models, and 200+ more. One install, every provider.', installCommand: 'npm install -g @gitlawb/openclaude@latest', npmUrl: 'https://www.npmjs.com/package/@gitlawb/openclaude', - github: 'https://github.com/Gitlawb/openclaude', - releasesUrl: 'https://github.com/Gitlawb/openclaude/releases', - gitlawb: 'https://gitlawb.com', + github: 'https://github.com/Twigpine/openclaude', + releasesUrl: 'https://github.com/Twigpine/openclaude/releases', + twigpine: 'https://twigpine.com', + // The node mirror path is unchanged: twigpine.com/node/repos/... redirects to + // the same explorer.gitlawb.com endpoint that gitlawb.com does, and neither + // currently serves this repo (404). Left as-is rather than swapped to a host + // that resolves no better. gitlawbRepo: 'https://gitlawb.com/node/repos/z6MkqDnb/openclaude', ogDefault: '/og/default.png', ogDocs: '/og/docs.png', diff --git a/web/src/layouts/DocsLayout.astro b/web/src/layouts/DocsLayout.astro index ca3e3083a0..2ba683465c 100644 --- a/web/src/layouts/DocsLayout.astro +++ b/web/src/layouts/DocsLayout.astro @@ -39,7 +39,7 @@ const jsonLd = [ url: new URL(path, SITE.url).href, isPartOf: { '@type': 'WebSite', name: SITE.name, url: SITE.url }, about: { '@type': 'SoftwareApplication', name: 'openclaude', url: SITE.url }, - author: { '@type': 'Organization', name: 'GitLawb', url: SITE.gitlawb }, + author: { '@type': 'Organization', name: 'Twigpine', url: SITE.twigpine }, }, ] --- diff --git a/web/src/pages/docs/index.astro b/web/src/pages/docs/index.astro index f22f6a4095..8660b2e5f9 100644 --- a/web/src/pages/docs/index.astro +++ b/web/src/pages/docs/index.astro @@ -24,9 +24,9 @@ const toc = [ local Ollama, gateways like OpenRouter and LiteLLM, and more.

- It is maintained by gitlawb and developed in + It is maintained by Twigpine and developed in the open on GitHub (with a mirror on the - gitlawb network). + Twigpine network).

{SITE.installCommand}
diff --git a/web/src/pages/index.astro b/web/src/pages/index.astro index 25a3773988..f4450d1140 100644 --- a/web/src/pages/index.astro +++ b/web/src/pages/index.astro @@ -61,7 +61,7 @@ const jsonLd = [ downloadUrl: SITE.npmUrl, description: SITE.description, offers: { '@type': 'Offer', price: '0', priceCurrency: 'USD' }, - author: { '@type': 'Organization', name: 'GitLawb', url: SITE.gitlawb }, + author: { '@type': 'Organization', name: 'Twigpine', url: SITE.twigpine }, }, { '@context': 'https://schema.org', @@ -75,7 +75,7 @@ const jsonLd = [
-

open source · gitlawb-aligned · model-neutral

+

open source · twigpine-aligned · model-neutral

runs anywhere.
uses anything.

diff --git a/web/src/styles/global.css b/web/src/styles/global.css index f740f7d234..1f08074207 100644 --- a/web/src/styles/global.css +++ b/web/src/styles/global.css @@ -1,5 +1,5 @@ /* ════════════════════════════════════════════════════════════════════════ - openclaude — gitlawb-aligned design tokens + openclaude — twigpine-aligned design tokens Monochrome surface system driven by --surface-rgb (inverts under light theme) + openclaude orange accent. Dark is the default theme. ════════════════════════════════════════════════════════════════════════ */ @@ -20,7 +20,7 @@ --accent-soft: rgba(255, 122, 26, 0.14); --accent-line: rgba(255, 122, 26, 0.4); - /* gitlawb semantic colors */ + /* twigpine semantic colors */ --green: #4ade80; --red: #f87171; --yellow: #facc15; @@ -136,7 +136,7 @@ h1[id], h2[id], h3[id], h4[id] { scroll-margin-top: calc(var(--nav-h) + 24px); } } .skip-link:focus { left: 0; } -/* ── type scale (gitlawb) ─────────────────────────────────────────────── */ +/* ── type scale (twigpine) ─────────────────────────────────────────────── */ .text-hero { font-size: clamp(2.5rem, 6vw, 3.75rem); From 1db7e0a4dec79eb23e43d82f4842f96b42e6b7e8 Mon Sep 17 00:00:00 2001 From: Gravirei Date: Thu, 1 Oct 2026 12:03:51 +0600 Subject: [PATCH 2/2] fix(aimlapi): stop matching topup intent on partnerName (#2246) partnerName is display metadata that travels alongside the partner id, not part of the intent identity. It is now excluded from INTENT_KEYS, so matchesIntent no longer requires it to be unchanged. Without this, renaming the partner on the Gitlawb -> Twigpine rebrand would have stranded any in-flight topup: a receipt persisted under the old name fails the strict equality check, so loadAimlapiTopupState returns null and the user restarts checkout. partnerId remains the identity field, so receipts are still scoped to the correct partner. Co-Authored-By: Claude Opus 4.8 (1M context) --- src/integrations/aimlapi/topupState.test.ts | 25 +++++++++++++++++++++ src/integrations/aimlapi/topupState.ts | 9 +++++++- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/src/integrations/aimlapi/topupState.test.ts b/src/integrations/aimlapi/topupState.test.ts index cfc9f46d01..69ee997682 100644 --- a/src/integrations/aimlapi/topupState.test.ts +++ b/src/integrations/aimlapi/topupState.test.ts @@ -103,6 +103,31 @@ test('top-up state round-trips only for the same checkout intent', () => { } }) +test('a receipt persisted under an older partnerName still resumes after a rebrand', () => { + // partnerName is display metadata, not identity: partnerId is what ties a + // receipt to an intent. A rename (Gitlawb -> Twigpine) must not strand a + // user mid-topup, so the persisted name is deliberately excluded from + // matchesIntent. + useTemporaryConfig() + const staleIntent: AimlapiTopupIntent = { ...intent, partnerName: 'Gitlawb' } + const claimed = claimAimlapiTopupState(staleIntent) + saveAimlapiTopupState({ + ...staleIntent, + paymentSessionId: claimed.paymentSessionId, + resumeSessionToken: 'session-token', + }) + + const current: AimlapiTopupIntent = { ...intent, partnerName: 'Twigpine' } + expect(loadAimlapiTopupState(current)).toEqual({ + paymentSessionId: claimed.paymentSessionId, + resumeSessionToken: 'session-token', + }) + // Still identity-scoped: a different partner id must not inherit the receipt. + expect( + loadAimlapiTopupState({ ...current, partnerId: 'part_other' }), + ).toBeNull() +}) + test('claimAimlapiTopupStateAsync behaves like the sync claim (non-blocking for the interactive flow)', async () => { useTemporaryConfig() diff --git a/src/integrations/aimlapi/topupState.ts b/src/integrations/aimlapi/topupState.ts index 47dffa5fba..028867679e 100644 --- a/src/integrations/aimlapi/topupState.ts +++ b/src/integrations/aimlapi/topupState.ts @@ -109,12 +109,19 @@ const KEY_MINT_LEASE_STALE_MS = 75_000 /** Owner-only file/dir modes; these records hold API credentials. */ const FILE_MODE = 0o600 const DIR_MODE = 0o700 +/** + * Identity fields for topup-intent matching, NOT `partnerName`. The partner id + * is the identity; `partnerName` is display metadata that travels alongside it + * and is free to change (it did, on the Gitlawb -> Twigpine rebrand). Matching + * on the name would strand a persisted receipt written under the old name, so a + * user resuming an in-flight topup after upgrading would fail `matchesIntent` and + * restart the checkout. + */ const INTENT_KEYS: ReadonlyArray = [ 'email', 'amountUsdMinor', 'autoTopUp', 'partnerId', - 'partnerName', 'appBaseUrl', 'inferenceBaseUrl', 'payBaseUrl',
- - GitLawb logo + + Twigpine logo @@ -57,7 +57,7 @@ OpenClaude is also mirrored to GitLawb:
GitLawbTwigpine Bankr.bot Atomic Chat Xiaomi MiMo