cngkit
v1.1.51
Published
Opinionated CNG CLI kit for Coderoom collaboration and operator workflows.
Readme
cngkit
CNG operator CLI for shared code rooms, safe local cleanup, local agent transcript inspection, and terminal access to the hosted Harness knowledge catalog.
cngkit is built for developers and AI agents who need practical commands that work
well in terminals, scripts, and coding assistants. Human-facing status lines use Ink
styling when the terminal supports color. Data-heavy output stays plain and easy to pipe.
Important Notice
cngkit is a personal-use project. I publish it because it solves problems I run into
in my own operator workflow, not because it is a polished community-maintained open-source
platform.
Assume backend-backed commands send their inputs, metadata, and command context to the owner-operated Curly.ng backend for processing. Do not use this package as a self-contained offline tool or neutral third-party service boundary.
If you need this to become a real open-source project, a self-hostable system, or a package with stronger data-processing guarantees, reach out first.
Quick Start
Run it without installing:
npx --yes cngkit@latest --helpOr install it globally:
npm install -g cngkit
cngkit --helpCheck the installed version:
cngkit --versioncngkit requires Node.js 20 or newer.
What It Does
cngkit login
cngkit setup --dry-run
cngkit coderoom share
cngkit coderoom join <room-code>
cngkit coderoom upload
cngkit coderoom download <room-code> --acceptance-token <token>
cngkit scrub [path]
cngkit transcripts list --limit 12
cngkit knowledges search Cloudflare --limit 3
cngkit knowledges cat topics/libraries/lib-cloudflare/TOPIC.md
cngkit knowledges playbooks playbook-project-environment-setup
cngkit env endpoint minimax
cngkit mobbin search "checkout address form" --platform ios --limit 5
cngkit mobbin download "profile settings screen" --platform ios --limit 3
cngkit crawl https://buildwithfern.com/learn/docs/ai-features/llms-txt --transcribe --json
cngkit hooks install
printf '{"hook":"PreToolUse"}' | cngkit hookify ingest --event PreToolUseThe CLI currently has eleven main jobs:
- Login: open the backend login flow for an operator.
- Setup: install or update Harness knowledges for local Claude and Codex use.
- Coderoom: share live rooms or fast short-lived working-tree snapshots.
- Scrub: scan local files for secrets and optionally mask them inline.
- Transcripts: inspect local Claude and Codex transcript files from the terminal.
- Knowledges: traverse, search, and read the hosted Harness knowledge catalog.
- Env: read
~/.agents/cngkit.tomland export canonical provider endpoints for local tools. - Mobbin: search Mobbin through the Cloudflare backend proxy and download screenshots.
- Crawl: discover robots.txt, sitemap URLs, recursive same-origin pages, and optional Claude transcripts.
- Hooks: install Hookify forwarding hooks into supported AI-assisted coding tools.
- Hookify: forward local hook events for server-side hook processing.
Env
cngkit env reads local provider configuration from ~/.agents/cngkit.toml.
Keep this file out of git and restrict it with chmod 600.
[env]
KLING_API_KEY = "..."
[providers.minimax]
api_key = "..."
base_url = "https://api.minimax.io/anthropic"
model = "minimax-m3"
[providers.glm]
api_key = "..."
base_url = "https://api.z.ai/api/anthropic"
model = "glm-5.2"
[claude]
api_timeout_ms = 3000000
disable_nonessential_traffic = truecngkit env load exports every [env] key plus the canonical derived provider
variables: MINIMAX_API_KEY, MINIMAX_BASE_URL, MINIMAX_MODEL, GLM_API_KEY,
GLM_BASE_URL, GLM_MODEL, API_TIMEOUT_MS, and
CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC.
Do not put these derived names in [env]; cngkit owns them from the provider
and Claude sections.
cngkit env endpoint minimax and cngkit env endpoint glm export
Claude-compatible ANTHROPIC_AUTH_TOKEN, ANTHROPIC_BASE_URL,
API_TIMEOUT_MS, CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC,
CNGKIT_PLATFORM_PROVIDER, and CNGKIT_PLATFORM_MODEL values.
Coderoom
Coderoom shares a working tree with another developer or agent through either a live
room or a fast short-lived snapshot.
Coderoom requires Git because Git owns the synced file set.
One machine can create a live room with share, or send a fast non-persistent snapshot with upload. share keeps a watcher running for live collaboration. upload prints a plan, asks for confirmation unless --yes is passed, uploads the current snapshot, prints a copy-ready download command with a guest acceptance token, and exits. The partner can use join for live collaboration or download for one-shot transfer.
Start a room:
cngkit coderoom shareJoin a room:
cngkit coderoom join <room-code> --acceptance-token <token>Upload a fast one-shot snapshot:
cngkit coderoom upload --yesDownload a fast one-shot snapshot:
cngkit coderoom download <room-code> --acceptance-token <token>Repo-local upload/download fixture:
docs/cngkit/coderoom-push-pull-demoCoderoom is a sync engine. It asks Git for tracked files and untracked files that
are not ignored, then applies extra safety filters for common dependency,
cache, virtualenv, and secret-looking paths such as node_modules, .venv,
.git, .next, .turbo, .aws, .ssh, .kube, .docker, .gnupg,
.env, .env.*, *.pem, and *.key. It supports binary files by transferring
base64 payloads. Room codes,
guest acceptance tokens, participants, join requests, and file IDs are created by the
backend. Room codes are short lowercase grouped codes like abc-defg-hij, similar to
meeting-room codes; tokens stay separate for authorization. The CLI prints every initial snapshot upload, live file upload, delete upload,
backend storage acknowledgement, and shutdown status. The room Durable Object stores the
file tree and hashes, keeps small file bodies directly, and uses R2 for large file bodies.
The current live conflict rule is simple: the latest received change wins. upload and download do not create a persistent session; they transfer one snapshot and exit. Uploads are one-time by default, so the backend removes the stored snapshot after the first successful download.
Harness Knowledges
The knowledges commands read the Cloudflare-backed Harness catalog. They are
read-only and designed for AI-friendly terminal use.
Install or update Harness knowledges locally:
cngkit setup --dry-run
cngkit setupsetup reads the public Harness setup plan from the configured backend, prints
the sync plan first, and writes only after confirmation unless --yes is
passed. Managed files live under ~/.agents, with Claude and Codex connected to
the central Harness skills directory.
Check catalog health:
cngkit knowledges statusBrowse the catalog like a remote filesystem:
cngkit knowledges ls .
cngkit knowledges ls topics/libraries/lib-cloudflare -l
cngkit knowledges tree topics/libraries --depth 2
cngkit knowledges ls topics/libraries/lib-cloudflare
cngkit knowledges stat topics/libraries/lib-cloudflare/TOPIC.md
cngkit knowledges realpath topics/libraries/lib-cloudflareFind relevant knowledge:
cngkit knowledges search Cloudflare --limit 3
cngkit knowledges playbooks playbook-project-environment-setupRead a catalog file:
cngkit knowledges cat topics/libraries/lib-cloudflare/TOPIC.md
cngkit knowledges head topics/libraries/lib-cloudflare/TOPIC.md -n 20
cngkit knowledges tail topics/libraries/lib-cloudflare/TOPIC.md -n 20
cngkit knowledges read topics/libraries/lib-cloudflare/TOPIC.md --limit 80Load predefined and project playbooks:
cngkit knowledges playbooks playbook-project-environment-setup
cngkit knowledges playbooks --cwd ~/usr/curly.ng
cngkit knowledges playbooks --no-project --limit 10Predefined playbooks come from hosted topics/playbooks/*/PLAYBOOK.md.
Project playbooks are local PLAYBOOK.md files found by walking upward from the
current directory or --cwd.
Find paths by shell-style filters:
cngkit knowledges find topics/libraries -name "*cloudflare*" -type fList matching files:
cngkit knowledges glob "**/*.md" --path topics/libraries/lib-cloudflareSearch inside files:
cngkit knowledges grep Cloudflare --path topics/libraries/lib-cloudflare --output-mode files_with_matchesReturn JSON for another tool:
cngkit knowledges status --json
cngkit --format json knowledges ls .
cngkit --format json knowledges tree topics/libraries --depth 2
cngkit --format json knowledges find topics/libraries -name "*cloudflare*" -type f
cngkit --format json knowledges stat topics/libraries/lib-cloudflare/TOPIC.md
cngkit --format json knowledges search "vector search" --limit 5Catalog paths are rooted at the Harness home folder. The important first-class
children are topics and skills. For example:
topics/libraries/lib-cloudflare/TOPIC.mdmeans:
~/.agents/topics/libraries/lib-cloudflare/TOPIC.mdThe knowledges command set is stateless. It does not keep a working directory and does
not provide interactive traversal commands; pass the path explicitly on each command.
Text output is shell-friendly:
lsprints one entry name per line; directories end with/. Use--longor-lfor the older metadata-heavy tab-separated output.treeprints a deterministic plain-text tree; directories end with/.cat,head, andtailprint raw file content only.find,glob, andgrep --output-mode files_with_matchesprint one path per line.read,glob, andrealpathremain useful agent/API-oriented helper commands.
Crawl
crawl starts from one HTTP URL, reads robots.txt, discovers sitemap URLs, and
falls back to bounded same-origin recursive crawling when a sitemap does not provide
page URLs.
cngkit crawl https://example.com
cngkit crawl https://example.com --mode robots
cngkit crawl https://example.com --mode sitemap --max-pages 500
cngkit crawl https://aitalent.genaifund.ai/ --mode recursive --max-depth 2 --max-pages 50Use --json for structured output with robots metadata, sitemap entries, crawled
pages, titles, links, and errors.
cngkit crawl https://buildwithfern.com/learn/docs/ai-features/llms-txt --jsonUse --transcribe when a local Claude CLI is available and you want clean Markdown
for AI ingestion. The command calls claude -p --dangerously-skip-permissions per
fetched page, caps the page content sent to Claude, and records a structured
transcription error instead of failing the whole crawl when Claude is missing,
slow, or unavailable.
cngkit crawl https://buildwithfern.com/learn/docs/ai-features/llms-txt \
--mode recursive \
--max-pages 1 \
--transcribe \
--transcribe-max-chars 80000 \
--jsonSecret Scrubbing
scrub scans a file or directory with TruffleHog and prints a redacted report.
cngkit scrub .Inline masking rewrites files, so it is gated behind --yes:
cngkit scrub . --yesMasked values use this format:
[CNGKIT_SECRET:<detector>:<verified|unverified>]scrub requires the trufflehog binary on PATH.
macOS install:
brew install trufflehogSafety notes:
- The default mode is report-only.
- Raw secret values are never printed.
--maskis accepted as a compatibility alias, but inline changes still require--yes.
Hookify
Use hooks install to configure supported local AI-assisted coding tools:
cngkit hooks install --dry-run
cngkit hooks install
cngkit hooks install --tool codex
cngkit hooks uninstall --dry-runThe installer currently writes user-level hook configuration for Claude Code and Codex.
It preserves existing non-cngkit hook handlers, replaces older cngkit Hookify handlers,
and installs cngkit hookify ingest --event <EventName> for every supported hook event
in each tool. Hook commands use the already-installed cngkit binary so hook execution
does not resolve cngkit@latest through npm on every event.
hooks uninstall removes current direct cngkit Hookify handlers and older npm/npx
cngkit@latest handlers, then reports the exact files, handler counts, and event names
it changed.
hookify is the hosted hook processing surface. The first command is intentionally
small: it reads stdin and forwards the raw payload to the backend. The backend can return
the hook result immediately or return a request id for workflow-backed processing; the CLI
polls until the final stdout, stderr, and exit code are ready.
cngkit hookify ingest --event PreToolUse < hook-payload.json
cngkit hookify ingest --event Stop --async < hook-payload.jsonThe backend response controls stdout and the process exit code. --async means the server
may defer the result behind a request id; it does not mean the local hook returns before the
final result is known. If the backend request or polling fails, the command falls back to
exit code 0 so local hooks do not block work because the remote service is unavailable.
Real backend forwarding requires CNGKIT_HOOKIFY_TOKEN or HOOKIFY_SECRET in the
hook process environment. The CLI sends that value as a bearer token and does not
print it. hooks install does not write secrets into hook config files.
Local Agent Transcripts
transcripts reads local JSONL files from:
~/.codex/sessions~/.codex/archived_sessions~/.claude/projects~/.claude/history.jsonl
List recent transcript files:
cngkit transcripts list --limit 12Read a transcript by path or partial session id:
cngkit transcripts read <path-or-session-id> --source codex --limit 80Search recent transcript entries:
cngkit transcripts grep "deploy failed" --source all --file-limit 60 --limit 20Transcript commands are local-only. They do not upload transcript content to the backend.
By default, they print user and assistant text and skip internal prompt, hook, and tool noise.
Use --include-internal when debugging transcript plumbing.
Backend
cngkit talks to this backend by default:
https://curly.ngOverride it for local or staging smoke work without persisting configuration:
cngkit --api-base-url http://localhost:8787 knowledges status
CNGKIT_API_BASE_URL=http://localhost:8787 cngkit knowledges statusOutput Format
Human-facing output renders as structured terminal text by default, including help screens and Markdown catalog reads. Use explicit formats when a script needs data or source text:
cngkit --format text --help
cngkit --format json knowledges status
cngkit --format markdown knowledges read topics/libraries/lib-cloudflare/TOPIC.md
cngkit --no-color knowledges status--json remains available on read-only data commands as a short alias for JSON output.
--format markdown is intentionally source-oriented; default terminal output should not
show raw Markdown syntax.
Help
Help is baked into the CLI and rendered for terminal reading:
cngkit --help
cngkit help
cngkit setup --help
cngkit help knowledges
cngkit coderoom --help
cngkit knowledges read --help
cngkit transcripts --help
cngkit hooks --help
cngkit hooks install --help
cngkit hooks uninstall --help
cngkit hookify --help
cngkit hookify ingest --helpHelp uses terminal Markdown rendering in interactive terminals and pipes. Status, warnings,
and errors use Ink color when the terminal supports it, while --format json, glob results,
grep results, and other parse-oriented output stay clean. Use --no-color or
CNGKIT_COLOR=never to disable CLI color, or CNGKIT_COLOR=always to force it in a wrapper
that does not report itself as a TTY.
Terminal UI Stack
cngkit uses the Ink family without adding a custom command framework:
- Pastel owns command and subcommand routing through files under
src/commands/. - Ink owns terminal rendering through built-in components such as
<Text>. - @inkkit/ink-markdown owns terminal Markdown rendering for help screens and Markdown catalog reads.
- Chalk owns the cngkit color theme passed into the Markdown renderer.
- Zod owns option and argument schemas for each route.
So yes, subcommands are built in through Pastel's nested route files. Adding a
subcommand is normally a new .tsx file under the matching command folder:
src/commands/
coderoom/
share.tsx cngkit coderoom share
join.tsx cngkit coderoom join
upload.tsx cngkit coderoom upload
download.tsx cngkit coderoom download
knowledges/
ls.tsx cngkit knowledges ls
tree.tsx cngkit knowledges tree
cat.tsx cngkit knowledges cat
head.tsx cngkit knowledges head
tail.tsx cngkit knowledges tail
find.tsx cngkit knowledges find
playbooks.tsx cngkit knowledges playbooks
stat.tsx cngkit knowledges stat
realpath.tsx cngkit knowledges realpath
read.tsx cngkit knowledges read
grep.tsx cngkit knowledges grep
glob.tsx cngkit knowledges glob
hooks/
install.tsx cngkit hooks install
uninstall.tsx cngkit hooks uninstall
hookify/
ingest.tsx cngkit hookify ingestThe CLI does not hand-roll ANSI escape codes. Status styles go through Ink's built-in
<Text color="..." bold dimColor> support, and help screens render through
@inkkit/ink-markdown with a shared Chalk-backed theme. Commands that return parse-oriented
content for agents or shell pipelines write clean lines instead.
For Contributors
The package source lives in apps/cng.
src/
cli/ Pastel bootstrap support, help text, option schemas, Ink output runner
commands/ Thin Pastel route files
features/ Command behavior grouped by feature
shared/ Config, theme, output, browser, API client, shared command utilitiesThe route files under src/commands/ should stay thin. Put behavior in
src/features/<feature>/, and put cross-feature runtime helpers in src/shared/.
For output, use the shared CommandOutput methods:
success,warning,info,muted, anderrorfor human-facing terminal status.markdownfor help screens and Markdown content that should render by default.rawfor JSON, explicit source output, file paths, grep results, and anything another tool may parse.
Useful local checks:
pnpm --filter cngkit run typecheck
pnpm --filter cngkit run lint
pnpm --filter cngkit run build
pnpm --filter cngkit run smokeRelease and install the newest npm package on the current machine:
pnpm --filter cngkit run deployThat command runs typecheck, lint, build, smoke, npm pack dry-run, npm publish, registry
verification, exact global install of the published version, and a final global
cngkit --version check.
The package build uses tsup to emit a file-preserving ESM build. The published binary is
dist/cli.js, and Pastel discovers command files under dist/commands/**.
License
Apache-2.0, with the personal-use and owner-operated backend notice above. If this helps you, support the workshop: https://curly.ng/support
