Skip to content

Commit 6768d25

Browse files
brtkwrclaude
andcommitted
feat: initial release of zeltapp cli
unofficial cli for the zelt hr platform, reverse-engineered from the web app. cookie+mfa auth (password stored in macos keychain with --remember), ttl disk cache, human-readable tables (or --json), shell completion, and 80%+ test coverage. commands cover: login/logout/whoami, me/people/leave/attendance/ calendar/expenses/company/reviews/goals plus raw escape hatch. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
0 parents  commit 6768d25

41 files changed

Lines changed: 5468 additions & 0 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/dependabot.yaml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
version: 2
2+
updates:
3+
- package-ecosystem: gomod
4+
directory: "/"
5+
schedule:
6+
interval: weekly
7+
open-pull-requests-limit: 5
8+
groups:
9+
go-deps:
10+
patterns:
11+
- "*"
12+
13+
- package-ecosystem: github-actions
14+
directory: "/"
15+
schedule:
16+
interval: weekly
17+
open-pull-requests-limit: 5
18+
groups:
19+
actions:
20+
patterns:
21+
- "*"

.github/workflows/ci.yaml

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [main]
6+
7+
jobs:
8+
test:
9+
uses: ./.github/workflows/test.yaml
10+
11+
release:
12+
needs: test
13+
runs-on: ubuntu-latest
14+
permissions:
15+
contents: write
16+
steps:
17+
- uses: actions/checkout@v4
18+
with:
19+
fetch-depth: 0
20+
21+
- name: Bump version and push tag
22+
id: tag
23+
uses: mathieudutour/github-tag-action@v6.2
24+
with:
25+
github_token: ${{ secrets.GITHUB_TOKEN }}
26+
default_bump: patch
27+
28+
- name: Fetch new tag
29+
run: git fetch --tags
30+
31+
- uses: actions/setup-go@v5
32+
with:
33+
go-version: stable
34+
35+
- name: Run GoReleaser
36+
uses: goreleaser/goreleaser-action@v6
37+
with:
38+
version: "~> v2"
39+
args: release --clean
40+
env:
41+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
42+
HOMEBREW_TAP_TOKEN: ${{ secrets.HOMEBREW_TAP_TOKEN }}
43+
GORELEASER_CURRENT_TAG: ${{ steps.tag.outputs.new_tag }}

.github/workflows/test.yaml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
name: Test
2+
3+
on:
4+
pull_request:
5+
branches: [main]
6+
workflow_call:
7+
8+
jobs:
9+
test:
10+
runs-on: ubuntu-latest
11+
steps:
12+
- uses: actions/checkout@v4
13+
14+
- uses: actions/setup-go@v5
15+
with:
16+
go-version: stable
17+
18+
- name: Run tests
19+
run: go test -v -cover ./...
20+
21+
- name: Build
22+
run: go build -o zeltapp ./cmd/zeltapp
23+
24+
- name: Vet
25+
run: go vet ./...

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
/zeltapp
2+
/zeltapp-cli
3+
*.test
4+
*.out
5+
.DS_Store

.goreleaser.yaml

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
version: 2
2+
3+
project_name: zeltapp
4+
5+
before:
6+
hooks:
7+
- go mod tidy
8+
9+
builds:
10+
- id: zeltapp
11+
main: ./cmd/zeltapp
12+
binary: zeltapp
13+
env:
14+
- CGO_ENABLED=0
15+
goos:
16+
- darwin
17+
- linux
18+
goarch:
19+
- amd64
20+
- arm64
21+
ldflags:
22+
- -s -w -X main.version={{ .Version }}
23+
24+
archives:
25+
- formats:
26+
- tar.gz
27+
name_template: "{{ .ProjectName }}_{{ .Os }}_{{ .Arch }}"
28+
29+
checksum:
30+
name_template: "checksums.txt"
31+
32+
brews:
33+
- repository:
34+
owner: agentic-utils
35+
name: homebrew-tap
36+
token: "{{ .Env.HOMEBREW_TAP_TOKEN }}"
37+
directory: Formula
38+
homepage: "https://github.com/agentic-utils/zeltapp-cli"
39+
description: "Unofficial CLI for the Zelt HR platform"
40+
license: "MIT"
41+
test: |
42+
system "#{bin}/zeltapp", "--version"
43+
44+
changelog:
45+
sort: asc
46+
filters:
47+
exclude:
48+
- "^docs:"
49+
- "^test:"
50+
- "^chore:"
51+
- "^ci:"

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2026 Bharat Kunwar
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
# zeltapp-cli
2+
3+
[![CI](https://github.com/agentic-utils/zeltapp-cli/actions/workflows/ci.yaml/badge.svg)](https://github.com/agentic-utils/zeltapp-cli/actions/workflows/ci.yaml)
4+
[![Go Report Card](https://goreportcard.com/badge/github.com/agentic-utils/zeltapp-cli)](https://goreportcard.com/report/github.com/agentic-utils/zeltapp-cli)
5+
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
6+
7+
unofficial CLI for [Zelt](https://zelt.app). reverse-engineered from the web app's `/apiv2/...` surface.
8+
9+
cookie-based session, email MFA prompted interactively on `login`. session lives at `~/.config/zeltapp-cli/session.json` (chmod 600).
10+
11+
## install
12+
13+
**homebrew** (macOS / linux):
14+
15+
```
16+
brew install agentic-utils/tap/zeltapp
17+
```
18+
19+
**go install**:
20+
21+
```
22+
go install github.com/agentic-utils/zeltapp-cli/cmd/zeltapp@latest
23+
```
24+
25+
**from source**:
26+
27+
```
28+
git clone https://github.com/agentic-utils/zeltapp-cli && cd zeltapp-cli
29+
go install ./cmd/zeltapp
30+
```
31+
32+
**prebuilt binaries**: see [releases](https://github.com/agentic-utils/zeltapp-cli/releases).
33+
34+
## usage
35+
36+
```
37+
zeltapp login # prompts for email, password, MFA code; saves password to Keychain
38+
zeltapp login --remember=false # same, but don't save the password
39+
zeltapp whoami
40+
zeltapp logout
41+
42+
zeltapp me profile # basic + personal + about
43+
zeltapp me contact # address + emergency + work contact
44+
zeltapp me employment # role + contracts + lifecycle
45+
zeltapp me compensation
46+
zeltapp me bank
47+
zeltapp me equity
48+
zeltapp me pension
49+
zeltapp me payslips
50+
zeltapp me devices
51+
zeltapp me benefits
52+
53+
zeltapp leave list
54+
zeltapp leave balance
55+
zeltapp leave book --policy 512 --start 2026-06-01 [--end 2026-06-02] [--notes "..."]
56+
zeltapp leave check --policy 512 --start 2026-06-01 # dry-run, shows cost + overlaps
57+
58+
zeltapp attendance today
59+
zeltapp attendance week
60+
61+
zeltapp calendar team [--start YYYY-MM-DD] [--end YYYY-MM-DD]
62+
63+
zeltapp expenses list
64+
65+
zeltapp company config
66+
zeltapp company departments
67+
zeltapp company sites
68+
zeltapp company jobs
69+
70+
zeltapp people list # company directory (active only)
71+
zeltapp people list --all # include inactive/terminated
72+
zeltapp people search "alice" # case-insensitive substring across name/email/dept/role
73+
zeltapp people get 6380 # one person by userId
74+
zeltapp people get alice@example.com # or by email
75+
76+
zeltapp reviews list # ongoing review cycles
77+
zeltapp reviews mine # my results across cycles
78+
zeltapp reviews cycle <uuid> # details + navigation for a cycle
79+
zeltapp reviews progress <uuid> # cycle + result progress
80+
zeltapp reviews participation <uuid> # participants in a cycle
81+
zeltapp reviews result <uuid> [--user N] # user-level result (default: self)
82+
zeltapp reviews entry [--user N] # review entry (default: self)
83+
84+
zeltapp goals list
85+
zeltapp goals mine
86+
87+
zeltapp cache list # show cached entries + TTLs
88+
zeltapp cache clear # wipe local cache
89+
90+
zeltapp raw GET /apiv2/users/cache # escape hatch
91+
zeltapp raw POST /apiv2/foo '{"x":1}'
92+
```
93+
94+
global flags:
95+
96+
```
97+
--json JSON output instead of human-readable tables
98+
-v, --verbose print request/response info to stderr
99+
--no-cache bypass the local TTL cache for this invocation
100+
```
101+
102+
## output format
103+
104+
by default, output is rendered as aligned tables (for lists) or key=value (for single records). pass `--json` to get the raw JSON response instead - useful for piping into `jq` or scripting.
105+
106+
```
107+
$ zeltapp leave policies
108+
ID NAME TYPE
109+
512 Annual Leave annual
110+
513 Sick Leave sick
111+
112+
$ zeltapp leave policies --json
113+
[
114+
{"id": 512, "name": "Annual Leave", "type": "annual"},
115+
...
116+
]
117+
```
118+
119+
## shell completion
120+
121+
zeltapp ships completion scripts via cobra. install once per shell:
122+
123+
**zsh** (most common on macOS):
124+
125+
```
126+
mkdir -p ~/.zsh/completions
127+
zeltapp completion zsh > ~/.zsh/completions/_zeltapp
128+
# add to ~/.zshrc if not already:
129+
# fpath=(~/.zsh/completions $fpath)
130+
# autoload -Uz compinit && compinit
131+
```
132+
133+
restart your shell or run `compinit` to pick it up.
134+
135+
**bash**:
136+
137+
```
138+
zeltapp completion bash > /usr/local/etc/bash_completion.d/zeltapp # macOS via brew install bash-completion@2
139+
# or:
140+
zeltapp completion bash > /etc/bash_completion.d/zeltapp # linux
141+
```
142+
143+
**fish**:
144+
145+
```
146+
zeltapp completion fish > ~/.config/fish/completions/zeltapp.fish
147+
```
148+
149+
**powershell**:
150+
151+
```
152+
zeltapp completion powershell > zeltapp.ps1
153+
# then source zeltapp.ps1 from your profile
154+
```
155+
156+
## notes
157+
158+
- email MFA: zelt emails a 6-digit code; paste it at the prompt.
159+
- access token expires after 15 min; refresh token lasts 30 days. The CLI auto-refreshes when the access token expires.
160+
- password is stored in macOS Keychain by default (service=`zeltapp-cli`). If the refresh token also expires (~30 days idle), the CLI re-logs in using the stored password and prompts only for the new MFA code. Pass `--remember=false` to login to opt out.
161+
- `leave book` will run `verify-overlap` + `request-value-and-balance2` first and show a confirmation prompt unless `--yes` is passed.
162+
- some endpoints are cached on disk at `~/.config/zeltapp-cli/cache/` with per-endpoint TTLs (e.g. `users/cache` 5 min, `companies/*` and `job-positions` 1 hour). pass `--no-cache` to bypass for one call, or run `zeltapp cache clear` to wipe everything. User-specific endpoints (`/users/<id>/*`, `auth/me`, absences, expenses, payroll) are never cached.

0 commit comments

Comments
 (0)