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.
- Demo video: https://github.com/yema7582-code/gwlingo/releases/download/v0.1.0/demo.mp4 (also playable in the repo at docs/demo.mp4)
- Release: https://github.com/yema7582-code/gwlingo/releases/tag/v0.1.0
- Gibwork toolset: SDK (
tasks.listAvailable,tasks.get) - Category: terminal utility and automation. No web app, no dashboard, no browser UI.
$ 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 日前
...
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 JSTand "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.
--detailsadds a creator-activity signal fromtasks.get: how many submissions the creator has reviewed and when they last acted. That answers "will anyone actually look at my work?"watchpolls 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
watchfrom cron and post Gibwork alerts into their own Discord or Telegram groups. That brings new contributors to Gibwork.
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:
listandshowprint to the terminal, or write Markdown/JSON files with--out.--format jsongives scripts and AI agents a stable, structured feed of localized bounties.watch --onceis 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.
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-walletcreates 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), whosesignTransactionalways 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.
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 doctorExpected 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)
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) |
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 |
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/TokyoOutput: 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.mdOutput: 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.jsonOutput: 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-bodyYou 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 discordStatus 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-bodyReal 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 ![]() |
show --lang ja ![]() |
list --lang zh --details ![]() |
list --match sdk,cli,mcp ![]() |
watch to webhook ![]() |
npm test ![]() |
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.
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.amountis converted from base units withBigInt, never with floats.- If translation fails (quota, network), gwlingo prints the original text with a warning and carries on.
If
tasks.getfails, 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.
npm test # TypeScript build plus 45 node:test cases; no network or wallet neededThe 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.
- Discovery needs a wallet signature (the API returns
401without one). The wallet frominit-walletis 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 rewardcompares USD value when--detailsprovides it and raw token amounts otherwise (CREDITS and USDC are not directly comparable).@gibwork/sdk0.2.0 is published asUNLICENSED. gwlingo installs it from npm and does not vendor it.
MIT for gwlingo's own code (see LICENSE). @gibwork/sdk is under its own terms.





