tlnt-cli 1.5.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- tlnt_cli-1.5.1/LICENSE +21 -0
- tlnt_cli-1.5.1/PKG-INFO +315 -0
- tlnt_cli-1.5.1/README.md +296 -0
- tlnt_cli-1.5.1/pyproject.toml +43 -0
- tlnt_cli-1.5.1/pyproject.toml.orig +39 -0
- tlnt_cli-1.5.1/src/tlnt/__init__.py +3 -0
- tlnt_cli-1.5.1/src/tlnt/__main__.py +4 -0
- tlnt_cli-1.5.1/src/tlnt/browser/__init__.py +0 -0
- tlnt_cli-1.5.1/src/tlnt/browser/login.py +414 -0
- tlnt_cli-1.5.1/src/tlnt/browser/oauth.py +50 -0
- tlnt_cli-1.5.1/src/tlnt/browser/scripted.py +183 -0
- tlnt_cli-1.5.1/src/tlnt/cli/__init__.py +0 -0
- tlnt_cli-1.5.1/src/tlnt/cli/avatars.py +51 -0
- tlnt_cli-1.5.1/src/tlnt/cli/commands/__init__.py +0 -0
- tlnt_cli-1.5.1/src/tlnt/cli/commands/approvals.py +98 -0
- tlnt_cli-1.5.1/src/tlnt/cli/commands/attendance.py +283 -0
- tlnt_cli-1.5.1/src/tlnt/cli/commands/calendar.py +108 -0
- tlnt_cli-1.5.1/src/tlnt/cli/commands/login.py +225 -0
- tlnt_cli-1.5.1/src/tlnt/cli/commands/logout.py +12 -0
- tlnt_cli-1.5.1/src/tlnt/cli/commands/mcp.py +8 -0
- tlnt_cli-1.5.1/src/tlnt/cli/commands/notifications.py +102 -0
- tlnt_cli-1.5.1/src/tlnt/cli/commands/profile.py +13 -0
- tlnt_cli-1.5.1/src/tlnt/cli/commands/setup.py +12 -0
- tlnt_cli-1.5.1/src/tlnt/cli/commands/status.py +12 -0
- tlnt_cli-1.5.1/src/tlnt/cli/commands/timeoff.py +491 -0
- tlnt_cli-1.5.1/src/tlnt/cli/commands/update.py +86 -0
- tlnt_cli-1.5.1/src/tlnt/cli/commands/version.py +15 -0
- tlnt_cli-1.5.1/src/tlnt/cli/main.py +163 -0
- tlnt_cli-1.5.1/src/tlnt/cli/options.py +56 -0
- tlnt_cli-1.5.1/src/tlnt/cli/output.py +321 -0
- tlnt_cli-1.5.1/src/tlnt/cli/prompts.py +76 -0
- tlnt_cli-1.5.1/src/tlnt/core/__init__.py +0 -0
- tlnt_cli-1.5.1/src/tlnt/core/clients/__init__.py +0 -0
- tlnt_cli-1.5.1/src/tlnt/core/clients/mekari/__init__.py +0 -0
- tlnt_cli-1.5.1/src/tlnt/core/clients/mekari/client.py +826 -0
- tlnt_cli-1.5.1/src/tlnt/core/clients/mekari/constants.py +174 -0
- tlnt_cli-1.5.1/src/tlnt/core/config.py +53 -0
- tlnt_cli-1.5.1/src/tlnt/core/http_client.py +110 -0
- tlnt_cli-1.5.1/src/tlnt/core/logs.py +34 -0
- tlnt_cli-1.5.1/src/tlnt/core/models.py +84 -0
- tlnt_cli-1.5.1/src/tlnt/core/play_store.py +85 -0
- tlnt_cli-1.5.1/src/tlnt/core/services/__init__.py +46 -0
- tlnt_cli-1.5.1/src/tlnt/core/services/attendance.py +213 -0
- tlnt_cli-1.5.1/src/tlnt/core/services/calendar.py +54 -0
- tlnt_cli-1.5.1/src/tlnt/core/services/login.py +100 -0
- tlnt_cli-1.5.1/src/tlnt/core/services/logout.py +38 -0
- tlnt_cli-1.5.1/src/tlnt/core/services/notifications.py +97 -0
- tlnt_cli-1.5.1/src/tlnt/core/services/profile.py +11 -0
- tlnt_cli-1.5.1/src/tlnt/core/services/setup.py +85 -0
- tlnt_cli-1.5.1/src/tlnt/core/services/status.py +35 -0
- tlnt_cli-1.5.1/src/tlnt/core/services/timeoff.py +146 -0
- tlnt_cli-1.5.1/src/tlnt/core/session.py +189 -0
- tlnt_cli-1.5.1/src/tlnt/core/user_agent.py +71 -0
- tlnt_cli-1.5.1/src/tlnt/mcp/__init__.py +0 -0
- tlnt_cli-1.5.1/src/tlnt/mcp/main.py +176 -0
tlnt_cli-1.5.1/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 fathiraz arthuro
|
|
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.
|
tlnt_cli-1.5.1/PKG-INFO
ADDED
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: tlnt-cli
|
|
3
|
+
Version: 1.5.1
|
|
4
|
+
Summary: CLI wrapper for HRIS attendance and employment workflows.
|
|
5
|
+
Author: Fathiraz Arthuro
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
License-File: LICENSE
|
|
8
|
+
Requires-Dist: httpx>=0.28,<0.29
|
|
9
|
+
Requires-Dist: keyring>=25,<26
|
|
10
|
+
Requires-Dist: loguru>=0.7,<1
|
|
11
|
+
Requires-Dist: mcp>=2.0,<3
|
|
12
|
+
Requires-Dist: platformdirs>=4.3,<5
|
|
13
|
+
Requires-Dist: playwright>=1.50,<2
|
|
14
|
+
Requires-Dist: rich>=14,<16
|
|
15
|
+
Requires-Dist: rich-pixels>=3,<4
|
|
16
|
+
Requires-Dist: typer>=0.20,<1
|
|
17
|
+
Requires-Python: >=3.11, <3.15
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
|
|
20
|
+

|
|
21
|
+
|
|
22
|
+
# tlnt
|
|
23
|
+
|
|
24
|
+

|
|
25
|
+

|
|
26
|
+
|
|
27
|
+
`tlnt` is a macOS Apple Silicon CLI for Mekari Talenta employment data,
|
|
28
|
+
notifications, attendance summaries and previews, and human-confirmed attendance actions.
|
|
29
|
+
|
|
30
|
+
> [!WARNING]
|
|
31
|
+
> `tlnt` is an unofficial, independent research and educational project. It
|
|
32
|
+
> is not affiliated with Mekari or Talenta. Use it only when your account and
|
|
33
|
+
> the actions you perform are authorized. Read the [full bilingual
|
|
34
|
+
> disclaimer](docs/index.md#disclaimer) before using it.
|
|
35
|
+
|
|
36
|
+
## Why tlnt?
|
|
37
|
+
|
|
38
|
+
- Inspect employment and notification data from the terminal.
|
|
39
|
+
- Read attendance summaries and metrics.
|
|
40
|
+
- Read time-off data and submit or cancel requests with confirmation.
|
|
41
|
+
- Preview attendance requests before submitting them.
|
|
42
|
+
- Keep login visible and live actions human-confirmed.
|
|
43
|
+
- Warn when a newer tlnt is on PyPI, or when your configured Talenta app
|
|
44
|
+
version differs from Google Play.
|
|
45
|
+
- Update itself with `tlnt update`.
|
|
46
|
+
- Provide stable JSON output and a read-only MCP server for agents.
|
|
47
|
+
|
|
48
|
+
## Install
|
|
49
|
+
|
|
50
|
+
Install from PyPI with [uv](https://docs.astral.sh/uv/):
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
uv tool install tlnt-cli
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Or use `pipx install tlnt-cli` or `pip install tlnt-cli`. PyPI refuses the name
|
|
57
|
+
`tlnt` as too similar to an existing project, so the package is `tlnt-cli`; the
|
|
58
|
+
command is still `tlnt`.
|
|
59
|
+
|
|
60
|
+
For other install methods (`uvx`, from source) and the agent-specific path,
|
|
61
|
+
choose the instructions for your audience:
|
|
62
|
+
|
|
63
|
+
- [For humans](docs/integrations.md#for-humans)
|
|
64
|
+
- [For LLM agents](docs/integrations.md#for-llm-agents)
|
|
65
|
+
|
|
66
|
+
Login uses Playwright to open your installed Google Chrome or Microsoft Edge;
|
|
67
|
+
nothing is downloaded. To use a browser you already run instead, see
|
|
68
|
+
[Sign in with your own browser](#sign-in-with-your-own-browser). To have tlnt
|
|
69
|
+
type your email and password for you, see
|
|
70
|
+
[Sign in from the terminal](#sign-in-from-the-terminal).
|
|
71
|
+
|
|
72
|
+
### Configure
|
|
73
|
+
|
|
74
|
+
Before first use, create the config file:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
tlnt setup
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
It creates `config.json` in the default OS config folder (or the file given
|
|
81
|
+
with `--config PATH`) with every supported key. Ask the project maintainers for
|
|
82
|
+
`client_id` and set it there. Run `tlnt setup` again after `tlnt update`: it
|
|
83
|
+
adds new keys, removes keys tlnt no longer reads, and keeps your values.
|
|
84
|
+
|
|
85
|
+
See [Setup](docs/setup.md) for configuration and login prerequisites.
|
|
86
|
+
`tlnt` never opens login automatically from another command.
|
|
87
|
+
|
|
88
|
+
### Sign in with your own browser
|
|
89
|
+
|
|
90
|
+
`tlnt login --cdp` attaches to a browser that is already running instead of
|
|
91
|
+
launching one. tlnt opens one tab in it, you sign in on Mekari's page, and only
|
|
92
|
+
that tab is closed. With Chrome, use a dedicated profile folder (Chrome 136 and
|
|
93
|
+
later ignore the DevTools port on the default profile):
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
# terminal 1: leave running
|
|
97
|
+
"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" \
|
|
98
|
+
--remote-debugging-port=9222 --user-data-dir="$HOME/.tlnt-chrome"
|
|
99
|
+
# terminal 2
|
|
100
|
+
tlnt login --cdp 9222
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
With agent-browser:
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
agent-browser --session tlnt-login --headed open about:blank
|
|
107
|
+
tlnt login --cdp "$(agent-browser --session tlnt-login get cdp-url)"
|
|
108
|
+
agent-browser --session tlnt-login close
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
See [Setup](docs/setup.md#sign-in-with-a-browser-you-already-run) for details.
|
|
112
|
+
|
|
113
|
+
### Sign in from the terminal
|
|
114
|
+
|
|
115
|
+
`tlnt login --email you@example.com` asks for your Mekari password with a hidden
|
|
116
|
+
prompt and types both into Mekari's own sign-in page. There is no `--password`
|
|
117
|
+
flag. See [Setup](docs/setup.md#sign-in-from-the-terminal) for hosts with no
|
|
118
|
+
terminal.
|
|
119
|
+
|
|
120
|
+
## Update tlnt
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
tlnt update
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
`tlnt update` installs the latest PyPI release with
|
|
127
|
+
`uv tool install tlnt-cli==<version> --force` when it is newer than the installed
|
|
128
|
+
version, and never downgrades. It needs `uv` on `PATH`, prints uv's output, and
|
|
129
|
+
exits with uv's exit code.
|
|
130
|
+
|
|
131
|
+
Installed tlnt 1.5.0 or earlier, when the package was still named `tlnt`?
|
|
132
|
+
Switch once:
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
uv tool install tlnt-cli --force && uv tool uninstall tlnt && uv tool install tlnt-cli --force
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
If the first install fails, nothing changes. Uninstalling the old package also
|
|
139
|
+
removes the `tlnt` command, so the last install puts it back. After that,
|
|
140
|
+
`tlnt update` works.
|
|
141
|
+
|
|
142
|
+
## tlnt version check
|
|
143
|
+
|
|
144
|
+
Every command except `mcp` and `update` also checks PyPI for a newer tlnt. If
|
|
145
|
+
one exists, a notice appears on stderr:
|
|
146
|
+
|
|
147
|
+
```text
|
|
148
|
+
⚠️ tlnt v1.4.0 is installed, but v1.5.0 is available. Run `tlnt update` to update.
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
The lookup times out after 3 seconds and its result is cached for 24 hours, a
|
|
152
|
+
failed lookup included, and the check stays silent when PyPI is unreachable. Stdout, `--json` results, and exit codes
|
|
153
|
+
are unchanged. The notice never updates anything by itself.
|
|
154
|
+
|
|
155
|
+
## Talenta app version check
|
|
156
|
+
|
|
157
|
+
Talenta requests carry the mobile app version from `app_version` in your
|
|
158
|
+
config. Every command except `mcp` and `update` compares it with the latest
|
|
159
|
+
version in the [Talenta Google Play
|
|
160
|
+
listing](https://play.google.com/store/apps/details?id=co.talenta&hl=id). If
|
|
161
|
+
they differ, a notice appears on stderr:
|
|
162
|
+
|
|
163
|
+
```text
|
|
164
|
+
⚠️ Talenta app v2.123.0 is configured, but v2.125.0 is on Google Play. Set "app_version" to "2.125.0" in /path/to/config.json (or TALENTA_APP_VERSION), then run `tlnt logout` and `tlnt login`.
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
Update `app_version` (and optionally `user_agent_mobile`; see
|
|
168
|
+
[Setup](docs/setup.md)), then log out and log in again. The lookup times out
|
|
169
|
+
after 3 seconds and its result is cached for 24 hours, a failed lookup
|
|
170
|
+
included, and the check stays silent when Google Play is unreachable. Stdout, `--json` results, and exit codes are
|
|
171
|
+
unchanged. The notice never logs out, logs in, or updates anything by itself.
|
|
172
|
+
|
|
173
|
+
## Modes at a glance
|
|
174
|
+
|
|
175
|
+
| Mode | Flag | Behavior |
|
|
176
|
+
| --- | --- | --- |
|
|
177
|
+
| Machine output | `--json` | Writes one result object to stdout. |
|
|
178
|
+
| Diagnostics | `--verbose` | Adds DEBUG diagnostics without changing stdout. |
|
|
179
|
+
| Safe preview | `--dry-run` | Builds an attendance preview without submitting it. |
|
|
180
|
+
| Configuration | `--config PATH` | Selects a config file for this invocation; pass it when a command needs values from a non-default file. Environment variables and the default OS config path need no flag. |
|
|
181
|
+
| Interactive input | `--interactive` | Prompts for missing values on supported commands; refuses to run without a TTY or with `--json`. |
|
|
182
|
+
|
|
183
|
+
Use `--json` when output will be consumed by an agent. Clock-in and
|
|
184
|
+
clock-out confirmation prompts use stdout in human mode and stderr with
|
|
185
|
+
`--json`; diagnostics use stderr.
|
|
186
|
+
|
|
187
|
+
## Common workflows
|
|
188
|
+
|
|
189
|
+
These examples assume settings come from the default OS config path or
|
|
190
|
+
environment variables. If you use a non-default config file, pass
|
|
191
|
+
`--config PATH` before each command that needs its values.
|
|
192
|
+
|
|
193
|
+
Read employment information:
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
tlnt profile --json
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
Read notifications and attendance summaries. Summary commands default to the
|
|
200
|
+
local date; use `--date YYYY-MM-DD` to select another day:
|
|
201
|
+
|
|
202
|
+
```bash
|
|
203
|
+
tlnt notification count --json
|
|
204
|
+
tlnt notification list --page 1 --query "" --status 3 --json
|
|
205
|
+
tlnt notification detail INBOX_ID --json
|
|
206
|
+
tlnt attendance summary-list --json
|
|
207
|
+
tlnt attendance summary-metrics --json
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
Preview, then explicitly confirm a live attendance action:
|
|
211
|
+
|
|
212
|
+
```bash
|
|
213
|
+
tlnt attendance clock-in \
|
|
214
|
+
--dry-run --latitude LATITUDE --longitude LONGITUDE --notes "Preview" --json
|
|
215
|
+
tlnt attendance clock-in \
|
|
216
|
+
--latitude LATITUDE --longitude LONGITUDE --notes "On time" --json
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
Review an attendance request before approval:
|
|
220
|
+
|
|
221
|
+
```bash
|
|
222
|
+
tlnt notification detail INBOX_ID --json
|
|
223
|
+
tlnt attendance approve INBOX_ID --reason "Reviewed" --json
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
See [Workflows](docs/workflows.md) for the complete safe procedures.
|
|
227
|
+
|
|
228
|
+
## Calendar commands
|
|
229
|
+
|
|
230
|
+
These calendar lookups are read-only and use the current Talenta mobile token.
|
|
231
|
+
Filtered commands default to `--limit 10` and `--page 1`; other filters are
|
|
232
|
+
sent only when supplied. `birthday` lists employee birthdays and can be
|
|
233
|
+
filtered to one employee with `--user-id`. `my-birthday` returns your
|
|
234
|
+
own birth date.
|
|
235
|
+
|
|
236
|
+
```bash
|
|
237
|
+
tlnt calendar holiday --start-date 2026-01-01 --end-date 2026-12-31 --json
|
|
238
|
+
tlnt calendar timeoff --start-date 2026-09-27 --end-date 2026-09-27 --json
|
|
239
|
+
tlnt calendar index --month 2 --year 2026 --json
|
|
240
|
+
tlnt calendar my-birthday --json
|
|
241
|
+
tlnt calendar birthday --start-date 2026-09-27 --end-date 2026-09-27 --json
|
|
242
|
+
tlnt calendar activity --start-date 2026-01-01 --end-date 2026-12-31 --json
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
Holiday, time-off, index, birthday, and activity commands also accept
|
|
246
|
+
`--start-date`, `--end-date`, `--limit`, `--month`, `--year`,
|
|
247
|
+
`--page`, `--id`, `--type`, `--search`, `--date`, and `--user-id`.
|
|
248
|
+
The personal `my-birthday` command has no filters.
|
|
249
|
+
|
|
250
|
+
## Time-off commands
|
|
251
|
+
|
|
252
|
+
Lookup commands are read-only. Time-off requests, approvals, and cancellations
|
|
253
|
+
require terminal confirmation; declining sends nothing. Balance requests use the signed-in
|
|
254
|
+
profile's company and user IDs.
|
|
255
|
+
|
|
256
|
+
```bash
|
|
257
|
+
tlnt timeoff types-list --json
|
|
258
|
+
tlnt timeoff balance --json
|
|
259
|
+
tlnt timeoff balance --show-unlimited-balance --json
|
|
260
|
+
tlnt timeoff delegation-list --search "NAME" --json
|
|
261
|
+
tlnt timeoff list --json
|
|
262
|
+
tlnt timeoff detail REQUEST_ID --json
|
|
263
|
+
tlnt timeoff request --date 2026-10-12 --policy-id 4448 --reason "reason"
|
|
264
|
+
tlnt timeoff request --date 2026-10-12 --policy-id 4448 --reason "reason" --half-day after --schedule-in 13:00 --schedule-out 18:00
|
|
265
|
+
tlnt timeoff request --date 2026-10-12 --policy-id 4448 --reason "reason" --half-day before --schedule-in 09:00 --schedule-out 12:00 --delegate-to 2378974 --file support.jpeg
|
|
266
|
+
tlnt timeoff cancel REQUEST_ID
|
|
267
|
+
tlnt timeoff approve INBOX_ID --reason "Reviewed"
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
See [Commands](docs/commands.md#time-off-data) for filters, defaults, and half-day details.
|
|
271
|
+
|
|
272
|
+
## Safety contract
|
|
273
|
+
|
|
274
|
+
- Do not open the login flow automatically.
|
|
275
|
+
- Never ask the user for their Mekari password. Only they start
|
|
276
|
+
`tlnt login --email`, and the password comes from a hidden prompt or from
|
|
277
|
+
`TALENTA_PASSWORD` in the host's own environment.
|
|
278
|
+
- Live clock-in, clock-out, approval, time-off requests, and cancellations always require terminal confirmation.
|
|
279
|
+
- `--dry-run` never submits attendance.
|
|
280
|
+
- MCP cannot log in, log out, approve attendance, or submit attendance.
|
|
281
|
+
- The version checks only read public listings (PyPI and Google Play), never
|
|
282
|
+
send your session or config, and never log out, log in, or update for you.
|
|
283
|
+
- Never print passwords, bearer tokens, cookies, authorization codes, request
|
|
284
|
+
bodies, selfie contents, or real employee data.
|
|
285
|
+
- If `status` returns `session_missing`, `session_invalid`,
|
|
286
|
+
`mobile_token_missing`, or `mobile_token_expired`, ask
|
|
287
|
+
the user to run login explicitly.
|
|
288
|
+
|
|
289
|
+
## Documentation
|
|
290
|
+
|
|
291
|
+
- [Docs site](https://tlnt-docs.vercel.app)
|
|
292
|
+
- [Cookbook](docs/cookbook.md)
|
|
293
|
+
- [Setup](docs/setup.md)
|
|
294
|
+
- [Commands and JSON contract](docs/commands.md)
|
|
295
|
+
- [Workflows](docs/workflows.md)
|
|
296
|
+
- [AI agent integrations](docs/integrations.md)
|
|
297
|
+
- [Security](docs/security.md)
|
|
298
|
+
- [Contributing](docs/contributing.md)
|
|
299
|
+
- [Agent skill](skills/tlnt-cli/SKILL.md)
|
|
300
|
+
|
|
301
|
+
## Troubleshooting
|
|
302
|
+
|
|
303
|
+
Login drives your installed Google Chrome or Microsoft Edge through
|
|
304
|
+
Playwright, so one of them must be installed, unless you attach to a browser you
|
|
305
|
+
already run with `tlnt login --cdp` (see [Setup](docs/setup.md#login)). Use `tlnt status --json` to inspect the local session without
|
|
306
|
+
contacting Talenta. Read [Security](docs/security.md) before removing a
|
|
307
|
+
session with `logout`. If the saved token already expired, `logout` still
|
|
308
|
+
removes the local session. If a command returns `mobile_token_expired` while
|
|
309
|
+
`tlnt login` says `Already logged in`, run `tlnt logout` and then
|
|
310
|
+
`tlnt login`. If a command prints the Google Play version notice,
|
|
311
|
+
see [App version check](#talenta-app-version-check).
|
|
312
|
+
|
|
313
|
+
## License
|
|
314
|
+
|
|
315
|
+
`tlnt` is licensed under the [MIT License](LICENSE).
|
tlnt_cli-1.5.1/README.md
ADDED
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+

|
|
2
|
+
|
|
3
|
+
# tlnt
|
|
4
|
+
|
|
5
|
+

|
|
6
|
+

|
|
7
|
+
|
|
8
|
+
`tlnt` is a macOS Apple Silicon CLI for Mekari Talenta employment data,
|
|
9
|
+
notifications, attendance summaries and previews, and human-confirmed attendance actions.
|
|
10
|
+
|
|
11
|
+
> [!WARNING]
|
|
12
|
+
> `tlnt` is an unofficial, independent research and educational project. It
|
|
13
|
+
> is not affiliated with Mekari or Talenta. Use it only when your account and
|
|
14
|
+
> the actions you perform are authorized. Read the [full bilingual
|
|
15
|
+
> disclaimer](docs/index.md#disclaimer) before using it.
|
|
16
|
+
|
|
17
|
+
## Why tlnt?
|
|
18
|
+
|
|
19
|
+
- Inspect employment and notification data from the terminal.
|
|
20
|
+
- Read attendance summaries and metrics.
|
|
21
|
+
- Read time-off data and submit or cancel requests with confirmation.
|
|
22
|
+
- Preview attendance requests before submitting them.
|
|
23
|
+
- Keep login visible and live actions human-confirmed.
|
|
24
|
+
- Warn when a newer tlnt is on PyPI, or when your configured Talenta app
|
|
25
|
+
version differs from Google Play.
|
|
26
|
+
- Update itself with `tlnt update`.
|
|
27
|
+
- Provide stable JSON output and a read-only MCP server for agents.
|
|
28
|
+
|
|
29
|
+
## Install
|
|
30
|
+
|
|
31
|
+
Install from PyPI with [uv](https://docs.astral.sh/uv/):
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
uv tool install tlnt-cli
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Or use `pipx install tlnt-cli` or `pip install tlnt-cli`. PyPI refuses the name
|
|
38
|
+
`tlnt` as too similar to an existing project, so the package is `tlnt-cli`; the
|
|
39
|
+
command is still `tlnt`.
|
|
40
|
+
|
|
41
|
+
For other install methods (`uvx`, from source) and the agent-specific path,
|
|
42
|
+
choose the instructions for your audience:
|
|
43
|
+
|
|
44
|
+
- [For humans](docs/integrations.md#for-humans)
|
|
45
|
+
- [For LLM agents](docs/integrations.md#for-llm-agents)
|
|
46
|
+
|
|
47
|
+
Login uses Playwright to open your installed Google Chrome or Microsoft Edge;
|
|
48
|
+
nothing is downloaded. To use a browser you already run instead, see
|
|
49
|
+
[Sign in with your own browser](#sign-in-with-your-own-browser). To have tlnt
|
|
50
|
+
type your email and password for you, see
|
|
51
|
+
[Sign in from the terminal](#sign-in-from-the-terminal).
|
|
52
|
+
|
|
53
|
+
### Configure
|
|
54
|
+
|
|
55
|
+
Before first use, create the config file:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
tlnt setup
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
It creates `config.json` in the default OS config folder (or the file given
|
|
62
|
+
with `--config PATH`) with every supported key. Ask the project maintainers for
|
|
63
|
+
`client_id` and set it there. Run `tlnt setup` again after `tlnt update`: it
|
|
64
|
+
adds new keys, removes keys tlnt no longer reads, and keeps your values.
|
|
65
|
+
|
|
66
|
+
See [Setup](docs/setup.md) for configuration and login prerequisites.
|
|
67
|
+
`tlnt` never opens login automatically from another command.
|
|
68
|
+
|
|
69
|
+
### Sign in with your own browser
|
|
70
|
+
|
|
71
|
+
`tlnt login --cdp` attaches to a browser that is already running instead of
|
|
72
|
+
launching one. tlnt opens one tab in it, you sign in on Mekari's page, and only
|
|
73
|
+
that tab is closed. With Chrome, use a dedicated profile folder (Chrome 136 and
|
|
74
|
+
later ignore the DevTools port on the default profile):
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
# terminal 1: leave running
|
|
78
|
+
"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" \
|
|
79
|
+
--remote-debugging-port=9222 --user-data-dir="$HOME/.tlnt-chrome"
|
|
80
|
+
# terminal 2
|
|
81
|
+
tlnt login --cdp 9222
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
With agent-browser:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
agent-browser --session tlnt-login --headed open about:blank
|
|
88
|
+
tlnt login --cdp "$(agent-browser --session tlnt-login get cdp-url)"
|
|
89
|
+
agent-browser --session tlnt-login close
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
See [Setup](docs/setup.md#sign-in-with-a-browser-you-already-run) for details.
|
|
93
|
+
|
|
94
|
+
### Sign in from the terminal
|
|
95
|
+
|
|
96
|
+
`tlnt login --email you@example.com` asks for your Mekari password with a hidden
|
|
97
|
+
prompt and types both into Mekari's own sign-in page. There is no `--password`
|
|
98
|
+
flag. See [Setup](docs/setup.md#sign-in-from-the-terminal) for hosts with no
|
|
99
|
+
terminal.
|
|
100
|
+
|
|
101
|
+
## Update tlnt
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
tlnt update
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
`tlnt update` installs the latest PyPI release with
|
|
108
|
+
`uv tool install tlnt-cli==<version> --force` when it is newer than the installed
|
|
109
|
+
version, and never downgrades. It needs `uv` on `PATH`, prints uv's output, and
|
|
110
|
+
exits with uv's exit code.
|
|
111
|
+
|
|
112
|
+
Installed tlnt 1.5.0 or earlier, when the package was still named `tlnt`?
|
|
113
|
+
Switch once:
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
uv tool install tlnt-cli --force && uv tool uninstall tlnt && uv tool install tlnt-cli --force
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
If the first install fails, nothing changes. Uninstalling the old package also
|
|
120
|
+
removes the `tlnt` command, so the last install puts it back. After that,
|
|
121
|
+
`tlnt update` works.
|
|
122
|
+
|
|
123
|
+
## tlnt version check
|
|
124
|
+
|
|
125
|
+
Every command except `mcp` and `update` also checks PyPI for a newer tlnt. If
|
|
126
|
+
one exists, a notice appears on stderr:
|
|
127
|
+
|
|
128
|
+
```text
|
|
129
|
+
⚠️ tlnt v1.4.0 is installed, but v1.5.0 is available. Run `tlnt update` to update.
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
The lookup times out after 3 seconds and its result is cached for 24 hours, a
|
|
133
|
+
failed lookup included, and the check stays silent when PyPI is unreachable. Stdout, `--json` results, and exit codes
|
|
134
|
+
are unchanged. The notice never updates anything by itself.
|
|
135
|
+
|
|
136
|
+
## Talenta app version check
|
|
137
|
+
|
|
138
|
+
Talenta requests carry the mobile app version from `app_version` in your
|
|
139
|
+
config. Every command except `mcp` and `update` compares it with the latest
|
|
140
|
+
version in the [Talenta Google Play
|
|
141
|
+
listing](https://play.google.com/store/apps/details?id=co.talenta&hl=id). If
|
|
142
|
+
they differ, a notice appears on stderr:
|
|
143
|
+
|
|
144
|
+
```text
|
|
145
|
+
⚠️ Talenta app v2.123.0 is configured, but v2.125.0 is on Google Play. Set "app_version" to "2.125.0" in /path/to/config.json (or TALENTA_APP_VERSION), then run `tlnt logout` and `tlnt login`.
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Update `app_version` (and optionally `user_agent_mobile`; see
|
|
149
|
+
[Setup](docs/setup.md)), then log out and log in again. The lookup times out
|
|
150
|
+
after 3 seconds and its result is cached for 24 hours, a failed lookup
|
|
151
|
+
included, and the check stays silent when Google Play is unreachable. Stdout, `--json` results, and exit codes are
|
|
152
|
+
unchanged. The notice never logs out, logs in, or updates anything by itself.
|
|
153
|
+
|
|
154
|
+
## Modes at a glance
|
|
155
|
+
|
|
156
|
+
| Mode | Flag | Behavior |
|
|
157
|
+
| --- | --- | --- |
|
|
158
|
+
| Machine output | `--json` | Writes one result object to stdout. |
|
|
159
|
+
| Diagnostics | `--verbose` | Adds DEBUG diagnostics without changing stdout. |
|
|
160
|
+
| Safe preview | `--dry-run` | Builds an attendance preview without submitting it. |
|
|
161
|
+
| Configuration | `--config PATH` | Selects a config file for this invocation; pass it when a command needs values from a non-default file. Environment variables and the default OS config path need no flag. |
|
|
162
|
+
| Interactive input | `--interactive` | Prompts for missing values on supported commands; refuses to run without a TTY or with `--json`. |
|
|
163
|
+
|
|
164
|
+
Use `--json` when output will be consumed by an agent. Clock-in and
|
|
165
|
+
clock-out confirmation prompts use stdout in human mode and stderr with
|
|
166
|
+
`--json`; diagnostics use stderr.
|
|
167
|
+
|
|
168
|
+
## Common workflows
|
|
169
|
+
|
|
170
|
+
These examples assume settings come from the default OS config path or
|
|
171
|
+
environment variables. If you use a non-default config file, pass
|
|
172
|
+
`--config PATH` before each command that needs its values.
|
|
173
|
+
|
|
174
|
+
Read employment information:
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
tlnt profile --json
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
Read notifications and attendance summaries. Summary commands default to the
|
|
181
|
+
local date; use `--date YYYY-MM-DD` to select another day:
|
|
182
|
+
|
|
183
|
+
```bash
|
|
184
|
+
tlnt notification count --json
|
|
185
|
+
tlnt notification list --page 1 --query "" --status 3 --json
|
|
186
|
+
tlnt notification detail INBOX_ID --json
|
|
187
|
+
tlnt attendance summary-list --json
|
|
188
|
+
tlnt attendance summary-metrics --json
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
Preview, then explicitly confirm a live attendance action:
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
tlnt attendance clock-in \
|
|
195
|
+
--dry-run --latitude LATITUDE --longitude LONGITUDE --notes "Preview" --json
|
|
196
|
+
tlnt attendance clock-in \
|
|
197
|
+
--latitude LATITUDE --longitude LONGITUDE --notes "On time" --json
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
Review an attendance request before approval:
|
|
201
|
+
|
|
202
|
+
```bash
|
|
203
|
+
tlnt notification detail INBOX_ID --json
|
|
204
|
+
tlnt attendance approve INBOX_ID --reason "Reviewed" --json
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
See [Workflows](docs/workflows.md) for the complete safe procedures.
|
|
208
|
+
|
|
209
|
+
## Calendar commands
|
|
210
|
+
|
|
211
|
+
These calendar lookups are read-only and use the current Talenta mobile token.
|
|
212
|
+
Filtered commands default to `--limit 10` and `--page 1`; other filters are
|
|
213
|
+
sent only when supplied. `birthday` lists employee birthdays and can be
|
|
214
|
+
filtered to one employee with `--user-id`. `my-birthday` returns your
|
|
215
|
+
own birth date.
|
|
216
|
+
|
|
217
|
+
```bash
|
|
218
|
+
tlnt calendar holiday --start-date 2026-01-01 --end-date 2026-12-31 --json
|
|
219
|
+
tlnt calendar timeoff --start-date 2026-09-27 --end-date 2026-09-27 --json
|
|
220
|
+
tlnt calendar index --month 2 --year 2026 --json
|
|
221
|
+
tlnt calendar my-birthday --json
|
|
222
|
+
tlnt calendar birthday --start-date 2026-09-27 --end-date 2026-09-27 --json
|
|
223
|
+
tlnt calendar activity --start-date 2026-01-01 --end-date 2026-12-31 --json
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
Holiday, time-off, index, birthday, and activity commands also accept
|
|
227
|
+
`--start-date`, `--end-date`, `--limit`, `--month`, `--year`,
|
|
228
|
+
`--page`, `--id`, `--type`, `--search`, `--date`, and `--user-id`.
|
|
229
|
+
The personal `my-birthday` command has no filters.
|
|
230
|
+
|
|
231
|
+
## Time-off commands
|
|
232
|
+
|
|
233
|
+
Lookup commands are read-only. Time-off requests, approvals, and cancellations
|
|
234
|
+
require terminal confirmation; declining sends nothing. Balance requests use the signed-in
|
|
235
|
+
profile's company and user IDs.
|
|
236
|
+
|
|
237
|
+
```bash
|
|
238
|
+
tlnt timeoff types-list --json
|
|
239
|
+
tlnt timeoff balance --json
|
|
240
|
+
tlnt timeoff balance --show-unlimited-balance --json
|
|
241
|
+
tlnt timeoff delegation-list --search "NAME" --json
|
|
242
|
+
tlnt timeoff list --json
|
|
243
|
+
tlnt timeoff detail REQUEST_ID --json
|
|
244
|
+
tlnt timeoff request --date 2026-10-12 --policy-id 4448 --reason "reason"
|
|
245
|
+
tlnt timeoff request --date 2026-10-12 --policy-id 4448 --reason "reason" --half-day after --schedule-in 13:00 --schedule-out 18:00
|
|
246
|
+
tlnt timeoff request --date 2026-10-12 --policy-id 4448 --reason "reason" --half-day before --schedule-in 09:00 --schedule-out 12:00 --delegate-to 2378974 --file support.jpeg
|
|
247
|
+
tlnt timeoff cancel REQUEST_ID
|
|
248
|
+
tlnt timeoff approve INBOX_ID --reason "Reviewed"
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
See [Commands](docs/commands.md#time-off-data) for filters, defaults, and half-day details.
|
|
252
|
+
|
|
253
|
+
## Safety contract
|
|
254
|
+
|
|
255
|
+
- Do not open the login flow automatically.
|
|
256
|
+
- Never ask the user for their Mekari password. Only they start
|
|
257
|
+
`tlnt login --email`, and the password comes from a hidden prompt or from
|
|
258
|
+
`TALENTA_PASSWORD` in the host's own environment.
|
|
259
|
+
- Live clock-in, clock-out, approval, time-off requests, and cancellations always require terminal confirmation.
|
|
260
|
+
- `--dry-run` never submits attendance.
|
|
261
|
+
- MCP cannot log in, log out, approve attendance, or submit attendance.
|
|
262
|
+
- The version checks only read public listings (PyPI and Google Play), never
|
|
263
|
+
send your session or config, and never log out, log in, or update for you.
|
|
264
|
+
- Never print passwords, bearer tokens, cookies, authorization codes, request
|
|
265
|
+
bodies, selfie contents, or real employee data.
|
|
266
|
+
- If `status` returns `session_missing`, `session_invalid`,
|
|
267
|
+
`mobile_token_missing`, or `mobile_token_expired`, ask
|
|
268
|
+
the user to run login explicitly.
|
|
269
|
+
|
|
270
|
+
## Documentation
|
|
271
|
+
|
|
272
|
+
- [Docs site](https://tlnt-docs.vercel.app)
|
|
273
|
+
- [Cookbook](docs/cookbook.md)
|
|
274
|
+
- [Setup](docs/setup.md)
|
|
275
|
+
- [Commands and JSON contract](docs/commands.md)
|
|
276
|
+
- [Workflows](docs/workflows.md)
|
|
277
|
+
- [AI agent integrations](docs/integrations.md)
|
|
278
|
+
- [Security](docs/security.md)
|
|
279
|
+
- [Contributing](docs/contributing.md)
|
|
280
|
+
- [Agent skill](skills/tlnt-cli/SKILL.md)
|
|
281
|
+
|
|
282
|
+
## Troubleshooting
|
|
283
|
+
|
|
284
|
+
Login drives your installed Google Chrome or Microsoft Edge through
|
|
285
|
+
Playwright, so one of them must be installed, unless you attach to a browser you
|
|
286
|
+
already run with `tlnt login --cdp` (see [Setup](docs/setup.md#login)). Use `tlnt status --json` to inspect the local session without
|
|
287
|
+
contacting Talenta. Read [Security](docs/security.md) before removing a
|
|
288
|
+
session with `logout`. If the saved token already expired, `logout` still
|
|
289
|
+
removes the local session. If a command returns `mobile_token_expired` while
|
|
290
|
+
`tlnt login` says `Already logged in`, run `tlnt logout` and then
|
|
291
|
+
`tlnt login`. If a command prints the Google Play version notice,
|
|
292
|
+
see [App version check](#talenta-app-version-check).
|
|
293
|
+
|
|
294
|
+
## License
|
|
295
|
+
|
|
296
|
+
`tlnt` is licensed under the [MIT License](LICENSE).
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["uv_build>=0.9,<0.13"]
|
|
3
|
+
build-backend = "uv_build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "tlnt-cli"
|
|
7
|
+
version = "1.5.1"
|
|
8
|
+
description = "CLI wrapper for HRIS attendance and employment workflows."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = "MIT"
|
|
11
|
+
license-files = ["LICENSE"]
|
|
12
|
+
requires-python = ">=3.11,<3.15"
|
|
13
|
+
dependencies = [
|
|
14
|
+
"httpx>=0.28,<0.29",
|
|
15
|
+
"keyring>=25,<26",
|
|
16
|
+
"loguru>=0.7,<1",
|
|
17
|
+
"mcp>=2.0,<3",
|
|
18
|
+
"platformdirs>=4.3,<5",
|
|
19
|
+
"playwright>=1.50,<2",
|
|
20
|
+
"rich>=14,<16",
|
|
21
|
+
"rich-pixels>=3,<4",
|
|
22
|
+
"typer>=0.20,<1",
|
|
23
|
+
]
|
|
24
|
+
|
|
25
|
+
[[project.authors]]
|
|
26
|
+
name = "Fathiraz Arthuro"
|
|
27
|
+
|
|
28
|
+
[project.scripts]
|
|
29
|
+
tlnt = "tlnt.cli.main:main"
|
|
30
|
+
|
|
31
|
+
[dependency-groups]
|
|
32
|
+
dev = ["pytest>=9,<10"]
|
|
33
|
+
docs = [
|
|
34
|
+
"mkdocs>=1.6,<2",
|
|
35
|
+
"mkdocs-shadcn>=0.9,<1",
|
|
36
|
+
]
|
|
37
|
+
|
|
38
|
+
[tool.uv.build-backend]
|
|
39
|
+
module-name = "tlnt"
|
|
40
|
+
|
|
41
|
+
[tool.pytest.ini_options]
|
|
42
|
+
addopts = "-q"
|
|
43
|
+
pythonpath = ["src"]
|