Skip to content
yema7582-codePublic

About

Read Gibwork bounties in Japanese, Chinese and English from your terminal, with push notifications. Built on the Gibwork SDK.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

gwlingo

Gibwork bounties in English, Japanese and Chinese, from the terminal.

gwlingo is a command-line tool built on the official @gibwork/sdk. It pulls open bounties from the Gibwork API and turns them into localized briefs, digests and chat notifications, with deadlines in your own time zone and eligibility rules spelled out in your language.

$ gwlingo show https://gib.work/bounty/1052f22d-3f87-4b1d-b0d7-71a60679e7fa --lang ja --tz Asia/Tokyo
[1] Gibwork開発者ハッカソン報酬  ja
    原文: Gibwork Developer Hackathon Bounty
    報酬プール        1,000 USDC
    締め切り          2026年10月30日(金) 13:00 JST (11 日後)
    提出数            12(審査中 12、承認 0)
    応募条件          • Discord サーバーへの参加が必要
                      • 特定の Discord ロール(1 個)が必要
    作成者の活動状況  ⚠ 停滞中 · 提出の 0% を審査済み · 最終アクションは 41 日前
    ...

Summary

Gibwork bounties are written in English and their deadlines come back from the API as UTC timestamps. If you live in Tokyo or Shenzhen and see 2026-10-30T04:00:00.000Z, you have to convert the time, paste the description into a translator, and then work out whether you can even take part (Premium only? Discord role? verified X account?).

gwlingo does that for you:

  • Titles and descriptions are machine-translated into Japanese, Chinese or English. The default backend is the free MyMemory API; any OpenAI-compatible LLM endpoint also works. A small Gibwork glossary keeps terms consistent, and results are cached on disk.
  • Rewards, deadlines, submission counts and eligibility rules are not machine-translated. They come from structured API fields and are rendered through hand-written templates for each language, so 1,000 USDC, 13:00 JST and "Discord role required" are always exact.
  • Deadlines are shown in your time zone and locale, with relative time ("11 日後", "34小时后").
  • An eligibility block lists Premium-only, verified-account, X follower, Discord server/role and slot limits.
  • --details adds a creator-activity signal from tasks.get: how many submissions the creator has reviewed and when they last acted. That answers "will anyone actually look at my work?"
  • watch polls for new bounties that match your filters and posts a localized message to Discord, Slack, Telegram, any JSON webhook or a desktop notification, or writes Markdown files.

Who it is for:

  • Builders who don't read English comfortably, or who just want deadlines in local time.
  • Community managers in Japanese and Chinese communities, who can run watch from cron and post Gibwork alerts into their own Discord or Telegram groups. That brings new contributors to Gibwork.

Why this is not a web app

gwlingo has no frontend and needs no browser. It is a Node.js CLI that you run in a terminal, in a cron job, in CI, or from another program:

  • list and show print to the terminal, or write Markdown/JSON files with --out.
  • --format json gives scripts and AI agents a stable, structured feed of localized bounties.
  • watch --once is designed for cron or systemd timers; state lives in ~/.local/state/gwlingo/, so each bounty is announced only once.
  • Notifications go out through webhooks and bots, which is where these communities already are.

How Gibwork is integrated

The Gibwork SDK is the only data source. Without it gwlingo has nothing to show.

gwlingo feature SDK call Notes
list, digest, watch client.tasks.listAvailable({ page, limit }) Discovery across all creators, paged (max 100 per page), honours Retry-After for the 30 req/min limit
show, --details client.tasks.get(taskId) Full content, Discord gating, review counts and health metrics
doctor listAvailable({ page: 1, limit: 1 }) Checks wallet auth end to end

The Gibwork External API (https://sdk.gib.work/v2/int/...) requires a wallet signature even for reads; an unauthenticated request gets 401. The SDK signs each request with a short-lived message signature (timestamp plus nonce). No transaction is involved, so discovery costs nothing.

gwlingo is read-only on purpose:

  • gwlingo init-wallet creates a new keypair that never needs funds (~/.config/gwlingo/discovery-keypair.json, mode 600). It is only used to sign auth messages.
  • The SDK signer is wrapped in readOnlySigner() (src/gibwork.ts), whose signTransaction always throws. gwlingo cannot create bounties, pay fees or move funds, even if you point it at a real wallet.

gwlingo uses the SDK rather than the Gibwork CLI or MCP server, because it needs typed responses for the templates and pagination. Its --format json output can be fed to an agent that also uses the Gibwork MCP.

Setup

Requirements: Node.js 22 or newer (required by @gibwork/sdk) and network access.

git clone https://github.com/yema7582-code/gwlingo.git
cd gwlingo
npm install
npm run build
npm link            # optional, puts `gwlingo` on your PATH; otherwise run `node dist/src/cli.js`

gwlingo init-wallet # one time: creates the discovery wallet (do not fund it)
gwlingo doctor

Expected doctor output:

gwlingo 0.1.0 · node v22.23.3
environment  production
wallet       7Gnr9VYRpmAsMDhKkKcs6Pxj99xK3BZMLJQApDbBtnxP  (/home/box/.config/gwlingo/discovery-keypair.json)
api          ok — tasks.listAvailable reports 6 open bounties
translator   mymemory
signing      read-only (transaction signing disabled in code)

Environment variables

All optional. See .env.example. gwlingo does not load .env itself; use node --env-file=.env dist/src/cli.js ... or export the variables.

Variable Purpose
GWLINGO_KEYPAIR / GIBWORK_KEYPAIR_PATH Keypair JSON used for API auth (default ~/.config/gwlingo/discovery-keypair.json)
GIBWORK_ENVIRONMENT production (default) or stage
GWLINGO_LANG Default output language: en, ja or zh (otherwise taken from $LANG)
GWLINGO_TRANSLATOR mymemory (default, free, no key), llm or none
MYMEMORY_EMAIL Raises MyMemory's free quota from about 5k to about 50k characters a day
GWLINGO_LLM_API_KEY, GWLINGO_LLM_BASE_URL, GWLINGO_LLM_MODEL Any OpenAI-compatible endpoint (OpenAI, xAI, OpenRouter, local Ollama or LM Studio)
TELEGRAM_BOT_TOKEN, TELEGRAM_CHAT_ID Used by watch --telegram
TZ Time zone for deadlines (or pass --tz)

Usage

gwlingo init-wallet                 Create a discovery wallet that never needs funds
gwlingo doctor                      Check wallet, environment and translator setup
gwlingo list   [filters] [output]   Localized digest of open bounties   (alias: digest)
gwlingo show   <task-id|url>        Full localized brief of one bounty
gwlingo watch  [filters] [notify]   Poll for new matching bounties and notify

Common options (run gwlingo --help for the full list):

Option
--lang ja,zh,en / --lang all One or more output languages
--translator mymemory|llm|none none keeps the original English text but still localizes the facts; works offline
--tz Asia/Tokyo Deadline time zone
--match a,b --exclude a,b --tag T --min-reward N --symbol USDC --no-premium Filters. Latin terms match whole words, CJK terms match as substrings; , , and 、 all work as separators
--details Fetch each bounty with tasks.get (creator activity, Discord gating)
--sort new|reward|deadline, --limit N Ordering
--format text|md|json, --out FILE Output format; --out writes a Markdown or JSON file
--no-body, --body-chars N Facts only, or cap description length to save translation quota

Sample input and output

All sample output in examples/ comes from real runs against the production Gibwork API.

1. Japanese brief for one bounty (takes an id or a gib.work URL)

gwlingo show https://gib.work/bounty/1052f22d-3f87-4b1d-b0d7-71a60679e7fa --lang ja --tz Asia/Tokyo

Output: examples/show-hackathon-ja.txt

2. Chinese digest sorted by reward, with creator activity, saved as Markdown

gwlingo list --lang zh --tz Asia/Shanghai --details --sort reward --body-chars 200 --out examples/digest-zh.md

Output: examples/digest-zh.txt (terminal) and examples/digest-zh.md (file)

[1] Gibwork开发者黑客马拉松悬赏  zh
    原文: Gibwork Developer Hackathon Bounty
    奖金池        1,000 USDC
    截止时间      2026年10月30日周五 GMT+8 12:00 (11天后)
    提交数        12(待审核 12、已通过 0)
    标签          Development
    参与条件      • 须加入 Discord 服务器
                  • 须拥有指定的 Discord 身份组(1 个)
    发布者活跃度  ⚠ 停滞 · 已审核 0% 的提交 · 发布者最后操作于 41 天前

3. Developer bounties as JSON for scripts or agents

gwlingo list --lang en --match sdk,cli,mcp,development --details --format json --out examples/digest-dev-en.json

Output: examples/digest-dev-en.json. Each item has the translated text, the original title, structured reward, eligibility, submissions and health fields, and a localized facts map.

4. Watch for new bounties and post them to Discord in Japanese

# poll every 15 minutes in the foreground
gwlingo watch --lang ja --match rust,solana,sdk --webhook "$DISCORD_WEBHOOK_URL" --webhook-format discord

# or one poll per cron run
*/15 * * * * gwlingo watch --once --lang zh --telegram --no-body

You can try this without any Discord account using the bundled mock receiver:

node scripts/mock-webhook.mjs 8787 &      # prints whatever it receives
gwlingo watch --once --lang ja --no-body --webhook http://127.0.0.1:8787/hook --webhook-format discord

Status log from two consecutive runs (examples/watch-once-ja.log):

[2026-10-19 22:48:26] scanned 6 matching bounties, 6 new
  ✓ notified via webhook:discord
  ✓ wrote examples/watch-output/gibwork-new-2026-10-19T13-48-26-444Z.md
[2026-10-19 22:48:27] scanned 6 matching bounties, 0 new

The second run finds nothing new, so nothing is sent twice. Bounties cut off by --limit are delivered on the next poll. Other files from this run: examples/watch-once-ja.txt (terminal), examples/webhook-payload-discord.json (the exact payload the webhook received) and examples/watch-output/ (the --out-dir Markdown file).

Message received by the webhook (excerpt; the bell is part of the message format):

🔔 Gibwork の新着バウンティ 6 件

▶ BASISの使用について1つの小さなことを共有する1つの角度を選ぶ
  報酬プール: 150 USDC · 締め切り: 2026年10月24日(土) 09:00 JST (4 日後)
  https://gib.work/bounty/48b29af8-6516-43cd-8407-0247497c0f9a

▶ Gibwork開発者ハッカソン報酬
  報酬プール: 1,000 USDC · 締め切り: 2026年10月30日(金) 13:00 JST (11 日後)
  応募条件: Discord サーバーへの参加が必要 / 特定の Discord ロール(1 個)が必要
  https://gib.work/bounty/1052f22d-3f87-4b1d-b0d7-71a60679e7fa
…

5. Offline mode. Runs against saved API responses, with no wallet and no network:

gwlingo list --fixtures test/fixtures --translator none --lang all --no-body

Screenshots

Real runs against the production Gibwork API, rendered by scripts/screenshots.mjs (ANSI to HTML to headless Chrome). The same images are attached to the v0.1.0 release.

doctor doctor show --lang ja show ja
list --lang zh --details digest zh list --match sdk,cli,mcp filter
watch to webhook watch npm test tests

Demo video

Watch or download: https://github.com/yema7582-code/gwlingo/releases/download/v0.1.0/demo.mp4

The same file is in the repo at docs/demo.mp4, where GitHub plays it in the browser. It is a 42-second, silent walkthrough of the real terminal runs shown above, in order: doctor, the Japanese brief, the Chinese digest, the developer filter, watch posting to a webhook, and the test suite. Rebuild it with npm run demo-video. docs/DEMO.md has a script for recording a longer live session.

Architecture

src/
  cli.ts            argument parsing, commands (list/show/watch/doctor/init-wallet)
  gibwork.ts        @gibwork/sdk client, read-only signer, pagination, Retry-After, fixture source
  app.ts            discovery, normalize, filter, sort, enrich
  model.ts          language-neutral Bounty model; lossless base-unit to decimal amounts
  html.ts           Gibwork HTML to structured plain text (lists, headings, links)
  i18n.ts           EN/JA/ZH labels and rule templates, Intl date and relative-time formatting
  localize.ts       decides which fields get machine-translated (title, description, requirements only)
  translate/        MyMemory and OpenAI-compatible providers, chunking, glossary, disk cache
  render.ts         terminal (CJK-aware wrapping and kinsoku), Markdown, JSON, chat messages
  width.ts          East Asian display width and wrapping
  match.ts state.ts notify.ts wallet.ts
test/               45 node:test cases, including a mock Gibwork API server that checks SDK auth headers

Design choices:

  • Only free text goes through machine translation. Anything numeric or rule-like comes from typed API fields. Translated text is always labelled as machine translation.
  • asset.amount is converted from base units with BigInt, never with floats.
  • If translation fails (quota, network), gwlingo prints the original text with a warning and carries on. If tasks.get fails, the discovery data is still shown.
  • Translation runs per paragraph or list item and is cached in ~/.cache/gwlingo, which keeps free quotas going further.

Tests

npm test     # TypeScript build plus 45 node:test cases; no network or wallet needed

The tests cover HTML conversion, exact amounts, both SDK response shapes, JA/ZH/EN templates and time zones, CJK width and wrapping, translation chunking, cache, glossary and fallback, the MyMemory and LLM request formats, filters, watch-state dedupe, webhook and Telegram payloads, and end-to-end CLI runs on fixtures. One test runs the SDK source against a local mock of the Gibwork API and checks that @gibwork/sdk sends the wallet-auth headers to /v2/int/tasks/available and /v2/int/tasks/:id.

Limitations

  • Discovery needs a wallet signature (the API returns 401 without one). The wallet from init-wallet is enough; it never needs SOL or USDC.
  • MyMemory's anonymous quota is about 5,000 characters a day. Set MYMEMORY_EMAIL, use --no-body, or switch to --translator llm.
  • --sort reward compares USD value when --details provides it and raw token amounts otherwise (CREDITS and USDC are not directly comparable).
  • @gibwork/sdk 0.2.0 is published as UNLICENSED. gwlingo installs it from npm and does not vendor it.

License

MIT for gwlingo's own code (see LICENSE). @gibwork/sdk is under its own terms.

About

Read Gibwork bounties in Japanese, Chinese and English from your terminal, with push notifications. Built on the Gibwork SDK.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages