agentleFS
darkamenosadarkamenosa/openzca/CLAUDE.md

openzca

CLAUDE.md105 starsChanged 9 months agoMITView on GitHub

openzca is a Node.js CLI for Zalo messaging (command-compatible with zca-cli.dev/docs), built on the zca-js library. It provides commands for authentication, messaging, group/friend management, profile updates, and real-time message listening. Installed globally via npm as openzca or zca. Tests live in tests/*.test.ts and selected src/lib/*.test.ts files, using the Node test runner through tsx. This is a single-entrypoint CLI app. All source lives in src/: Key patterns: - The CLI uses Commander.js with a root program and subcommands (e.g., program.command("auth") with…

  • Reads credentials
  • Installs packages
  • Commits and pushes
  • In this repositoryOne other file it gives its agents.

The file

We split this CLAUDE.md into the rules it gives an agent

3 rules. About 0 are common, 1 is distinctive, and 2 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈1

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 2

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    All Zalo API calls go through zca-js types (API, Credentials, Zalo, etc.).

    line 42
  2. Very specific:

    All commands use the pattern: zca --profile <profile> <command> [args]

    line 50
  3. Distinctive:

    Name resolution: Only at startup; newly added users aren't resolved until restart

    line 75

≈ “Common” is an estimate: at least 1 in 5 of the 26,980 CLAUDE.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
CLAUDE.md

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Project Overview

openzca is a Node.js CLI for Zalo messaging (command-compatible with zca-cli.dev/docs), built on the zca-js library. It provides commands for authentication, messaging, group/friend management, profile updates, and real-time message listening. Installed globally via npm as openzca or zca.

Commands

npm install          # install dependencies
npm test             # run the Node test suite via tsx
npm run build        # build with tsup (ESM, node22 target) → dist/
npm run dev          # run directly via tsx (no build needed)
npm run typecheck    # full TypeScript check (tsc --noEmit)
npm run lint         # same as typecheck
node dist/cli.js     # run built CLI

Tests live in tests/*.test.ts and selected src/lib/*.test.ts files, using the Node test runner through tsx.

Architecture

This is a single-entrypoint CLI app. All source lives in src/:

  • src/cli.ts (~5400 lines) — The entire CLI definition using Commander.js. Contains all command registration (auth, msg, group, friend, me, listen, account) and their action handlers in one file. This is the main file you'll edit for any command changes.
  • src/lib/client.ts — Zalo API client wrapper: QR login, credential-based login, session creation via zca-js.
  • src/lib/store.ts — Profile/credential/cache persistence under ~/.openzca/. Multi-profile support with profiles.json and per-profile credentials.json + cache.
  • src/lib/media.ts — Media file handling utilities: URL downloading to temp files, file validation, tilde expansion, content-type mapping.
  • src/lib/video-send.ts — Native video-send helper: ffmpeg/ffprobe detection, local thumbnail generation, Zalo upload orchestration, and fallback decision logic for msg video.
  • src/lib/text-styles.ts — Markdown-to-Zalo text style parser: bold, italic, strikethrough, headings, lists, indents, blockquotes, fenced code, color/underline tags.
  • src/lib/text-send.ts — Text send payload builder: combines text styles and outbound group mentions into a final message payload.
  • src/lib/group-mentions.ts — Outbound @mention resolution for group messages: matches @Name/@userId against the group member list.
  • src/lib/group-poll.ts — Poll CLI validation helpers: poll ID parsing, option ID validation, and CreatePollOptions construction.
  • src/lib/types.ts — Shared TypeScript interfaces (StoredCredentials, ProfilesDb, ProfileCachePayload, ProfileMeta).

Key patterns:

  • The CLI uses Commander.js with a root program and subcommands (e.g., program.command("auth") with nested .command("login")).
  • Global options --profile, --debug, --debug-file are on the root command.
  • The listen command is the most complex — handles WebSocket reconnection, media downloading, supervised mode lifecycle events, and raw JSON output enrichment.
  • All Zalo API calls go through zca-js types (API, Credentials, Zalo, etc.).

OpenClaw OpenZalo / ZaloUser Plugin Compatibility

openzca is the CLI backend for the OpenClaw OpenZalo channel plugin and its legacy zalouser variant. The plugin spawns openzca as a subprocess for all Zalo operations. Any CLI changes must remain compatible with how the plugin calls the binary.

How the plugin calls openzca

All commands use the pattern: zca --profile <profile> <command> [args]

CategoryCommands used by plugin
Authauth login, auth login --qr-base64, auth status, auth logout, auth cache-refresh
Messagingmsg send <id> <text> [-g], msg image <id> -u <url> [-m caption] [-g], msg video <id> -u <url> [-g], msg voice <id> -u <url> [-g], msg link <id> <url> [-g]
Listeninglisten -r -k (raw + keep-alive streaming)
Friendsfriend list -j, friend find <name> -j, friend online
Groupsgroup list -j, group info <id>, group members <id> -j
Profileme info -j, me id

Key flags: -j (JSON output), -r (raw mode), -k (keep-alive), -g (group target), -u (media URL), -m (caption).

Video send behavior:

  • msg video now attempts native Zalo display-video mode for a single local or downloaded .mp4 by generating or accepting a thumbnail, uploading both assets to Zalo, and calling api.sendVideo(...).
  • Native mode requires ffmpeg; if ffmpeg is unavailable, the input is not a single .mp4, or native send fails, the command falls back to the older api.sendMessage({ attachments }) path.
  • Video/file uploads must run under the upload-listener flow (withUploadListener(...)) because zca-js waits for the websocket file_done callback before resolving uploads.

Known plugin limitations (motivation for future improvements)

  • Text limit: 2000 chars max per message
  • No thread/reply support: threads: false in plugin capabilities
  • No native commands: OpenClaw command syntax not directly supported
  • Stream blocking: blockStreaming: true prevents concurrent sends during stream processing
  • Group member cache: 5-minute TTL only; dynamic group changes lag
  • Name resolution: Only at startup; newly added users aren't resolved until restart
  • No rate limiting: Relies on zca-js internal limits
  • Unofficial API: Built on reverse-engineered Zalo APIs; risk of account suspension

These limitations will be addressed in a new improved plugin. When adding features to openzca, consider whether they help lift these constraints.

Environment Variables

Key env vars used at runtime (not for development):

  • OPENZCA_HOME — override default ~/.openzca data directory
  • OPENZCA_PROFILE — select active profile without --profile flag
  • ZCA_PROFILE — legacy profile env var alias (kept for backward compatibility)
  • OPENZCA_DEBUG=1 — enable debug logging
  • OPENZCA_LISTEN_* — various listener config (media dir, timeouts, recycle intervals)
  • OPENCLAW_STATE_DIR / CLAWDBOT_STATE_DIR — OpenClaw integration media storage path

Release Process

Required order — always execute in this exact sequence:

  1. Update version
  2. Commit
  3. Tag
  4. Release on GitHub
  5. Publish to npm
# 1) Update version
npm version <new_version> --no-git-tag-version

# Validate
npm test && npm run lint && npm run typecheck && npm run build

# 2) Commit
git add package.json package-lock.json README.md docs/ src/ tests/ AGENTS.md CLAUDE.md
git commit -m "release: v<new_version>"

# 3) Tag
git tag -a v<new_version> -m "openzca v<new_version>"
git push origin main
git push origin v<new_version>

# 4) GitHub release
gh release create v<new_version> \
  --repo darkamenosa/openzca \
  --title "v<new_version>" \
  --notes "Release v<new_version>"

# 5) npm publish
npm publish

# Verify
npm dist-tag ls openzca
npm view openzca@latest version

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.