Skip to content

Commit f6eaf37

Browse files
committed
clean up documentation for npm users
1 parent 2620720 commit f6eaf37

13 files changed

Lines changed: 84 additions & 86 deletions

File tree

README.md

Lines changed: 40 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
# abacus-cli
22

3-
CLI tool for automating time entry logging in [Abacus ERP](https://www.abacus.ch) via Playwright browser automation.
3+
CLI tool for logging time entries in [Abacus ERP](https://www.abacus.ch) from the terminal.
44

5-
[Abacus](https://www.abacus.ch) is a Swiss ERP system widely used by companies in Switzerland for accounting, payroll, and time tracking. Its web portal is built on Vaadin (a server-side Java UI framework) and does not expose a REST API — so this tool uses headless browser automation instead. The CLI drives a real Chromium browser, fills forms, reads grids, and handles Vaadin's async server round-trips.
5+
[Abacus](https://www.abacus.ch) is a Swiss ERP system widely used for accounting, payroll, and time tracking. Its web portal does not expose a REST API, so this tool uses Playwright to drive a headless Chromium browser — filling forms, reading grids, and handling the UI automatically.
6+
7+
**[Documentation](https://wassertim.github.io/abacus-cli/en/)**
68

79
## Who is this for?
810

@@ -13,33 +15,32 @@ This project is open source under the MIT license. You're welcome to fork it, ad
1315
## Prerequisites
1416

1517
- Node.js 18+
16-
- A running Abacus instance you have credentials for
18+
- Access to an Abacus web portal (provided by your company)
1719

1820
## Setup
1921

22+
```bash
23+
npm install -g abacus-cli
24+
```
25+
26+
Chromium is downloaded automatically on install for browser automation.
27+
28+
### From source
29+
2030
```bash
2131
git clone https://github.com/wassertim/abacus-cli.git
2232
cd abacus-cli
2333
npm install
2434
npm run build
25-
npm link # makes `abacus` available globally
35+
npm link
2636
```
2737

28-
### Configuration
29-
30-
Set your Abacus instance URL via environment variable:
38+
### Configure your Abacus URL
3139

3240
```bash
33-
export ABACUS_URL="https://your-abacus-instance.example.com/portal/myabacus"
41+
abacus config set url https://your-abacus-instance.example.com/portal/myabacus
3442
```
3543

36-
| Variable | Default | Description |
37-
|----------|---------|-------------|
38-
| `ABACUS_URL` | `https://abacus.example.com/portal/myabacus` | Base URL of your Abacus portal |
39-
| `ABACUS_CONFIG_DIR` | `~/.abacus-cli` | Directory for session state and discovery data |
40-
41-
## Usage
42-
4344
### Login
4445

4546
Opens a real browser window for manual login. Session cookies are persisted locally so subsequent commands run headlessly.
@@ -48,17 +49,19 @@ Opens a real browser window for manual login. Session cookies are persisted loca
4849
abacus login
4950
```
5051

52+
## Usage
53+
5154
### Log time
5255

5356
```bash
54-
abacus time log --project 71100000001 --hours 8 --service-type 1435 --text "Development" --date 2025-01-15
57+
abacus time log --project 12345 --hours 8 --service-type 100 --text "Development" --date 2025-01-15
5558
```
5659

5760
| Flag | Required | Default | Description |
5861
|------|----------|---------|-------------|
5962
| `--project <id>` | no || Project number or alias (interactive prompt if omitted) |
6063
| `--hours <n>` | yes || Hours to log |
61-
| `--service-type <id>` | no | `1435` | Service type ID or alias |
64+
| `--service-type <id>` | no | `100` | Service type ID or alias |
6265
| `--text <text>` | yes || Description |
6366
| `--date <YYYY-MM-DD>` | no | today | Entry date |
6467

@@ -87,13 +90,13 @@ Create multiple time entries in a single browser session — much faster than ru
8790

8891
```bash
8992
# Fill current week (Mon-Fri)
90-
abacus time batch --project 71100000001 --hours 8 --service-type 1435 --text "Development"
93+
abacus time batch --project 12345 --hours 8 --service-type 100 --text "Development"
9194

9295
# Fill specific date range
93-
abacus time batch --from 2026-01-26 --to 2026-01-30 --project 71100000001 --hours 8 --text "Dev"
96+
abacus time batch --from 2026-01-26 --to 2026-01-30 --project 12345 --hours 8 --text "Dev"
9497

9598
# Preview what would be created
96-
abacus time batch --project 71100000001 --hours 8 --text "Dev" --dry-run
99+
abacus time batch --project 12345 --hours 8 --text "Dev" --dry-run
97100
```
98101

99102
**Generate template** — finds missing days and writes a pre-filled file:
@@ -116,21 +119,21 @@ abacus time batch --file entries.json --include-weekends
116119
JSON format:
117120
```json
118121
[
119-
{ "date": "2026-02-02", "project": "71100000001", "serviceType": "1435", "hours": 8, "text": "Development" }
122+
{ "date": "2026-02-02", "project": "12345", "serviceType": "100", "hours": 8, "text": "Development" }
120123
]
121124
```
122125

123126
CSV format:
124127
```
125128
date,project,serviceType,hours,text
126-
2026-02-02,71100000001,1435,8,Development
129+
2026-02-02,12345,100,8,Development
127130
```
128131

129132
| Flag | Description |
130133
|------|-------------|
131134
| `--project <id>` | Project number or alias (required for range fill) |
132135
| `--hours <n>` | Hours per entry (required for range fill) |
133-
| `--service-type <id>` | Service type (default: 1435) |
136+
| `--service-type <id>` | Service type (default: 100) |
134137
| `--text <text>` | Description |
135138
| `--from <YYYY-MM-DD>` | Start date (default: Monday of current week) |
136139
| `--to <YYYY-MM-DD>` | End date (default: Friday of current week) |
@@ -155,7 +158,7 @@ This opens a checkbox picker with all entries for the current month. Navigate wi
155158
**Targeted mode** — delete a specific entry by date and project:
156159

157160
```bash
158-
abacus time delete --date 2025-01-15 --project 71100000001
161+
abacus time delete --date 2025-01-15 --project 12345
159162
```
160163

161164
| Flag | Required | Description |
@@ -201,8 +204,8 @@ Create short names for frequently used project numbers and service types.
201204

202205
```bash
203206
abacus alias list
204-
abacus alias add project myproj 71100000001
205-
abacus alias add service-type dev 1435
207+
abacus alias add project myproj 12345
208+
abacus alias add service-type dev 100
206209
abacus alias remove project myproj
207210
```
208211

@@ -220,6 +223,13 @@ abacus config set url https://your-instance.example.com/portal/myabacus
220223
abacus config set locale de # Override locale (de, en, fr, it, es)
221224
```
222225

226+
Environment variables can also be used:
227+
228+
| Variable | Default | Description |
229+
|----------|---------|-------------|
230+
| `ABACUS_URL` || Base URL of your Abacus portal |
231+
| `ABACUS_CONFIG_DIR` | `~/.abacus-cli` | Directory for session state |
232+
223233
### Session refresh
224234

225235
Keep your saved session alive by refreshing it periodically. On macOS, you can install a launchd agent to do this automatically.
@@ -241,11 +251,13 @@ abacus discover
241251

242252
## How it works
243253

254+
Abacus's web portal is built on [Vaadin](https://vaadin.com/), a server-side Java UI framework. There is no REST API — every interaction happens through the browser DOM with server round-trips for each action.
255+
244256
1. **Login** — Opens a headed browser for manual SSO/login. Saves cookies and localStorage to `~/.abacus-cli/state.json`.
245-
2. **Automation** — Restores the saved session in a headless browser. Navigates to the Leistungen (time entries) page via Vaadin's menu system.
257+
2. **Automation** — Restores the saved session in a headless browser and navigates through Vaadin's menu system to the time entries page.
246258
3. **Vaadin handling** — Comboboxes require character-by-character input with delays to trigger server-side filtering. `waitForVaadin()` polls the client to ensure no pending server requests before proceeding.
247259
4. **Duplicate detection** — Before creating an entry, existing entries for the same date and project are checked. You can choose to update or create new.
248-
5. **Captcha fallback** — If a FortiADC captcha is detected, the browser reopens in headed mode for manual solving, then retries automatically.
260+
5. **Captcha fallback** — If a captcha is detected, the browser reopens in headed mode for manual solving, then retries automatically.
249261

250262
## Development
251263

site/public/og-image.png

29.8 KB
Loading

site/public/og-image.svg

Lines changed: 1 addition & 1 deletion
Loading

site/src/i18n/de.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,10 @@ export default {
3232
},
3333
howItWorks: {
3434
title: 'So funktioniert es',
35-
step1: 'Login — Öffnet einen echten Browser für manuelles SSO/Login. Die Session wird lokal gespeichert.',
36-
step2: 'Automatisierung — Stellt die Session headless wieder her und navigiert durch Vaadins UI.',
37-
step3: 'Smarte Eingabe — Zeichen-für-Zeichen Combobox-Eingabe, Server-Roundtrip-Polling, Duplikaterkennung.',
38-
step4: 'Captcha-Fallback — Falls ein Captcha erscheint, öffnet sich der Browser zur manuellen Lösung und versucht es dann erneut.',
35+
step1: 'Einmal im echten Browser einloggen. Ihre Session wird lokal gespeichert.',
36+
step2: 'Beliebigen Befehl ausführen — ein unsichtbarer Browser öffnet sich, stellt Ihre Session wieder her und erledigt die Arbeit.',
37+
step3: 'Bestehende Einträge werden automatisch erkannt, damit keine Duplikate entstehen.',
38+
step4: 'Falls Ihr Unternehmen ein Captcha nutzt, öffnet sich der Browser zur manuellen Lösung und fährt dann fort.',
3939
},
4040
},
4141
gettingStarted: {

site/src/i18n/en.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,10 @@ export default {
3232
},
3333
howItWorks: {
3434
title: 'How it works',
35-
step1: 'Login — Opens a real browser for manual SSO/login. Session is saved locally.',
36-
step2: 'Automation — Restores the session headlessly and navigates Vaadin\'s UI.',
37-
step3: 'Smart handling — Character-by-character combobox input, server round-trip polling, duplicate detection.',
38-
step4: 'Captcha fallback — If a captcha appears, the browser reopens for manual solving, then retries.',
35+
step1: 'Log in once in a real browser window. Your session is saved locally.',
36+
step2: 'Run any command — it opens a headless browser, restores your session, and does the work.',
37+
step3: 'Existing entries are detected automatically so you don\'t create duplicates.',
38+
step4: 'If your company uses a captcha, the browser reopens so you can solve it, then continues.',
3939
},
4040
},
4141
gettingStarted: {

site/src/layouts/Base.astro

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,17 +31,19 @@ const alternateUrl = `https://wassertim.github.io${localePath(other, pagePath)}`
3131
<link rel="canonical" href={canonicalUrl} />
3232
<link rel="alternate" hreflang={locale} href={canonicalUrl} />
3333
<link rel="alternate" hreflang={other} href={alternateUrl} />
34+
<link rel="alternate" hreflang="x-default" href={canonicalUrl} />
3435

36+
<meta property="og:locale" content={locale === 'de' ? 'de_DE' : 'en_US'} />
3537
<meta property="og:type" content="website" />
3638
<meta property="og:title" content={title} />
3739
<meta property="og:description" content={description} />
3840
<meta property="og:url" content={canonicalUrl} />
39-
<meta property="og:image" content="https://wassertim.github.io/abacus-cli/og-image.svg" />
41+
<meta property="og:image" content="https://wassertim.github.io/abacus-cli/og-image.png" />
4042

4143
<meta name="twitter:card" content="summary_large_image" />
4244
<meta name="twitter:title" content={title} />
4345
<meta name="twitter:description" content={description} />
44-
<meta name="twitter:image" content="https://wassertim.github.io/abacus-cli/og-image.svg" />
46+
<meta name="twitter:image" content="https://wassertim.github.io/abacus-cli/og-image.png" />
4547

4648
<link rel="icon" type="image/svg+xml" href="/abacus-cli/favicon.svg" />
4749
</head>

site/src/pages/de/docs/configuration.astro

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ const t = getTranslations(locale);
2222
<thead><tr><th>Variable</th><th>Standard</th><th>Beschreibung</th></tr></thead>
2323
<tbody>
2424
<tr><td><code>ABACUS_URL</code></td><td><code>https://abacus.example.com/portal/myabacus</code></td><td>Basis-URL Ihres Abacus-Portals</td></tr>
25-
<tr><td><code>ABACUS_CONFIG_DIR</code></td><td><code>~/.abacus-cli</code></td><td>Verzeichnis für Session-Daten und Discovery-Dateien</td></tr>
25+
<tr><td><code>ABACUS_CONFIG_DIR</code></td><td><code>~/.abacus-cli</code></td><td>Verzeichnis für Session-Daten</td></tr>
2626
<tr><td><code>ABACUS_LOCALE</code></td><td>automatisch erkannt</td><td>UI-Sprache überschreiben (de, en, fr, it, es)</td></tr>
2727
</tbody>
2828
</table>
@@ -39,8 +39,8 @@ abacus config set locale de # Sprache überschreiben (de, en, fr
3939
<p>Kurznamen für häufig verwendete Projektnummern und Leistungsarten erstellen.</p>
4040
<CodeBlock>
4141
<pre><code>abacus alias list
42-
abacus alias add project meinprojekt 71100000001
43-
abacus alias add service-type entw 1435
42+
abacus alias add project meinprojekt 12345
43+
abacus alias add service-type entw 100
4444
abacus alias remove project meinprojekt</code></pre>
4545
</CodeBlock>
4646
<p>Einmal definiert, können Aliase überall statt numerischer IDs verwendet werden:</p>

site/src/pages/de/docs/index.astro

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,14 @@ const t = getTranslations(locale);
2525
<h2 id="time-log">abacus time log</h2>
2626
<p>Einen einzelnen Zeiteintrag erfassen.</p>
2727
<CodeBlock>
28-
<pre><code>abacus time log --project 71100000001 --hours 8 --service-type 1435 --text "Entwicklung" --date 2025-01-15</code></pre>
28+
<pre><code>abacus time log --project 12345 --hours 8 --service-type 100 --text "Entwicklung" --date 2025-01-15</code></pre>
2929
</CodeBlock>
3030
<table>
3131
<thead><tr><th>Flag</th><th>Pflicht</th><th>Standard</th><th>Beschreibung</th></tr></thead>
3232
<tbody>
3333
<tr><td><code>--project &lt;id&gt;</code></td><td>nein</td><td>—</td><td>Projektnummer oder Alias (interaktive Auswahl falls weggelassen)</td></tr>
3434
<tr><td><code>--hours &lt;n&gt;</code></td><td>ja</td><td>—</td><td>Zu erfassende Stunden</td></tr>
35-
<tr><td><code>--service-type &lt;id&gt;</code></td><td>nein</td><td><code>1435</code></td><td>Leistungsart-ID oder Alias</td></tr>
35+
<tr><td><code>--service-type &lt;id&gt;</code></td><td>nein</td><td><code>100</code></td><td>Leistungsart-ID oder Alias</td></tr>
3636
<tr><td><code>--text &lt;text&gt;</code></td><td>ja</td><td>—</td><td>Beschreibung</td></tr>
3737
<tr><td><code>--date &lt;YYYY-MM-DD&gt;</code></td><td>nein</td><td>heute</td><td>Datum des Eintrags</td></tr>
3838
</tbody>
@@ -58,13 +58,13 @@ abacus time list --monthYear 01.2025 # bestimmter Monat</code></pre>
5858
<p>Füllt alle Wochentage in einem Zeitraum:</p>
5959
<CodeBlock>
6060
<pre><code># Aktuelle Woche füllen (Mo-Fr)
61-
abacus time batch --project 71100000001 --hours 8 --service-type 1435 --text "Entwicklung"
61+
abacus time batch --project 12345 --hours 8 --service-type 100 --text "Entwicklung"
6262

6363
# Bestimmten Zeitraum füllen
64-
abacus time batch --from 2026-01-26 --to 2026-01-30 --project 71100000001 --hours 8 --text "Entw."
64+
abacus time batch --from 2026-01-26 --to 2026-01-30 --project 12345 --hours 8 --text "Entw."
6565

6666
# Vorschau ohne Erstellung
67-
abacus time batch --project 71100000001 --hours 8 --text "Entw." --dry-run</code></pre>
67+
abacus time batch --project 12345 --hours 8 --text "Entw." --dry-run</code></pre>
6868
</CodeBlock>
6969

7070
<h3>Vorlage generieren</h3>
@@ -89,7 +89,7 @@ abacus time batch --file eintraege.json --include-weekends</code></pre>
8989
<tbody>
9090
<tr><td><code>--project &lt;id&gt;</code></td><td>Projektnummer oder Alias (Pflicht bei Bereichsfüllung)</td></tr>
9191
<tr><td><code>--hours &lt;n&gt;</code></td><td>Stunden pro Eintrag (Pflicht bei Bereichsfüllung)</td></tr>
92-
<tr><td><code>--service-type &lt;id&gt;</code></td><td>Leistungsart (Standard: 1435)</td></tr>
92+
<tr><td><code>--service-type &lt;id&gt;</code></td><td>Leistungsart (Standard: 100)</td></tr>
9393
<tr><td><code>--text &lt;text&gt;</code></td><td>Beschreibung</td></tr>
9494
<tr><td><code>--from &lt;YYYY-MM-DD&gt;</code></td><td>Startdatum (Standard: Montag der aktuellen Woche)</td></tr>
9595
<tr><td><code>--to &lt;YYYY-MM-DD&gt;</code></td><td>Enddatum (Standard: Freitag der aktuellen Woche)</td></tr>
@@ -110,7 +110,7 @@ abacus time batch --file eintraege.json --include-weekends</code></pre>
110110

111111
<p><strong>Gezielter Modus</strong> — bestimmten Eintrag nach Datum und Projekt löschen:</p>
112112
<CodeBlock>
113-
<pre><code>abacus time delete --date 2025-01-15 --project 71100000001</code></pre>
113+
<pre><code>abacus time delete --date 2025-01-15 --project 12345</code></pre>
114114
</CodeBlock>
115115

116116
<h2 id="summary">abacus summary</h2>
@@ -132,9 +132,4 @@ Overtime: +12.5h (1.6d) · Vacation: 15.0d left
132132
<pre><code>abacus check 2>/dev/null</code></pre>
133133
</CodeBlock>
134134

135-
<h2 id="discover">abacus discover</h2>
136-
<p>Zeichnet Netzwerkanfragen auf, während Sie manuell mit Abacus interagieren. Nützlich zum Verstehen von Vaadins Kommunikationsprotokoll.</p>
137-
<CodeBlock>
138-
<pre><code>abacus discover</code></pre>
139-
</CodeBlock>
140135
</Docs>

site/src/pages/de/getting-started.astro

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,14 @@ const t = getTranslations(locale);
1919
<h2 id="prerequisites">{t.gettingStarted.prerequisites}</h2>
2020
<ul>
2121
<li>Node.js 18+</li>
22-
<li>Eine laufende Abacus-Instanz, für die Sie Zugangsdaten haben</li>
22+
<li>Zugang zu einem Abacus-Webportal (von Ihrem Unternehmen bereitgestellt)</li>
2323
</ul>
2424

2525
<h2 id="installation">{t.gettingStarted.installation}</h2>
2626
<CodeBlock title="Terminal">
27-
<pre><code>git clone https://github.com/wassertim/abacus-cli.git
28-
cd abacus-cli
29-
npm install
30-
npm run build
31-
npm link # macht `abacus` global verfügbar</code></pre>
27+
<pre><code>npm install -g abacus-cli</code></pre>
3228
</CodeBlock>
29+
<p>Chromium wird bei der Installation automatisch heruntergeladen.</p>
3330

3431
<h2 id="configuration">{t.gettingStarted.configuration}</h2>
3532
<p>Setzen Sie die URL Ihrer Abacus-Instanz als Umgebungsvariable:</p>
@@ -58,7 +55,7 @@ npm link # macht `abacus` global verfügbar</code></pre>
5855
<tr>
5956
<td><code>ABACUS_CONFIG_DIR</code></td>
6057
<td><code>~/.abacus-cli</code></td>
61-
<td>Verzeichnis für Session-Daten und Discovery-Dateien</td>
58+
<td>Verzeichnis für Session-Daten</td>
6259
</tr>
6360
</tbody>
6461
</table>
@@ -71,7 +68,7 @@ npm link # macht `abacus` global verfügbar</code></pre>
7168

7269
<h2 id="first-entry">{t.gettingStarted.firstEntry}</h2>
7370
<CodeBlock>
74-
<pre><code>abacus time log --project 71100000001 --hours 8 --service-type 1435 --text "Entwicklung"</code></pre>
71+
<pre><code>abacus time log --project 12345 --hours 8 --service-type 100 --text "Entwicklung"</code></pre>
7572
</CodeBlock>
7673
<p>Falls ein passender Eintrag (gleiches Datum + Projekt) bereits existiert, werden Sie gefragt, ob Sie ihn aktualisieren oder einen neuen erstellen möchten.</p>
7774

site/src/pages/en/docs/configuration.astro

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ const t = getTranslations(locale);
2222
<thead><tr><th>Variable</th><th>Default</th><th>Description</th></tr></thead>
2323
<tbody>
2424
<tr><td><code>ABACUS_URL</code></td><td><code>https://abacus.example.com/portal/myabacus</code></td><td>Base URL of your Abacus portal</td></tr>
25-
<tr><td><code>ABACUS_CONFIG_DIR</code></td><td><code>~/.abacus-cli</code></td><td>Directory for session state and discovery data</td></tr>
25+
<tr><td><code>ABACUS_CONFIG_DIR</code></td><td><code>~/.abacus-cli</code></td><td>Directory for session state</td></tr>
2626
<tr><td><code>ABACUS_LOCALE</code></td><td>auto-detected</td><td>Override the UI locale (de, en, fr, it, es)</td></tr>
2727
</tbody>
2828
</table>
@@ -39,8 +39,8 @@ abacus config set locale de # Override locale (de, en, fr, it, e
3939
<p>Create short names for frequently used project numbers and service types.</p>
4040
<CodeBlock>
4141
<pre><code>abacus alias list
42-
abacus alias add project myproj 71100000001
43-
abacus alias add service-type dev 1435
42+
abacus alias add project myproj 12345
43+
abacus alias add service-type dev 100
4444
abacus alias remove project myproj</code></pre>
4545
</CodeBlock>
4646
<p>Once defined, use aliases anywhere instead of numeric IDs:</p>

0 commit comments

Comments
 (0)