@geneverse/workctl 0.2.5 → 0.2.10
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.
- package/README.md +45 -297
- package/dist/packages/cli/src/release-version.js +1 -1
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -1,339 +1,87 @@
|
|
|
1
1
|
# workctl
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
is available through `workctl jira`.
|
|
5
|
-
|
|
6
|
-
```bash
|
|
7
|
-
workctl jira sync
|
|
8
|
-
workctl update
|
|
9
|
-
workctl setup
|
|
10
|
-
workctl jenkins job create --help
|
|
11
|
-
workctl assistant status
|
|
12
|
-
```
|
|
13
|
-
|
|
14
|
-
The npm package contains the compiled CLI, this README, and the MIT license.
|
|
15
|
-
Project planning and architecture notes live in the source repository and are
|
|
16
|
-
not included in the published package.
|
|
17
|
-
|
|
18
|
-
## jira capability
|
|
19
|
-
|
|
20
|
-
Deterministic local CLI for synchronizing Kawari timesheets to Jira Cloud.
|
|
21
|
-
No double-entry — scrape your timesheet, review what will be created, and
|
|
22
|
-
approve once.
|
|
3
|
+
`workctl` syncs Kawari timesheets to Jira Cloud worklogs.
|
|
23
4
|
|
|
24
5
|
## Quick Start
|
|
25
6
|
|
|
26
|
-
**Prerequisites:** Node.js
|
|
7
|
+
**Prerequisites:** Node.js >=22, a Jira Cloud API token, and access to your
|
|
27
8
|
Kawari timesheet.
|
|
28
9
|
|
|
29
10
|
```bash
|
|
30
11
|
npm install -g @geneverse/workctl
|
|
31
12
|
workctl browsers install
|
|
32
13
|
workctl setup
|
|
14
|
+
workctl jira preview
|
|
15
|
+
workctl jira sync
|
|
33
16
|
```
|
|
34
17
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
onboarding asks only for Jira email and API token, supplies the company
|
|
38
|
-
defaults, verifies the result, and writes a private user-global configuration
|
|
39
|
-
file. Re-running setup skips configuration that is already valid and verifies
|
|
40
|
-
it again.
|
|
18
|
+
`preview` is read-only. Use it first to confirm what will be created in Jira.
|
|
19
|
+
`sync` asks for approval before writing worklogs.
|
|
41
20
|
|
|
42
21
|
## Configuration
|
|
43
22
|
|
|
44
|
-
Run `workctl
|
|
45
|
-
|
|
46
|
-
Link Status Audit. On macOS and Linux, configuration is stored at
|
|
47
|
-
`~/.config/workctl/config.json`; on Windows, it is stored under
|
|
48
|
-
`%APPDATA%\workctl\config.json`. POSIX directories and files use private
|
|
49
|
-
permissions. The Jira token is stored as plain text in that file, so use
|
|
50
|
-
workctl only on a trusted personal workstation.
|
|
23
|
+
Run `workctl setup` for the normal first-time setup. It configures Jira sync,
|
|
24
|
+
verifies the result, and writes a private user configuration file.
|
|
51
25
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
| `jiraBaseUrl` | `JIRA_BASE_URL` | Jira Cloud HTTPS origin |
|
|
55
|
-
| `jiraEmail` | `JIRA_EMAIL` | Your Jira account email |
|
|
56
|
-
| `jiraApiToken` | `JIRA_API_TOKEN` | Jira Cloud API token ([create one here](https://id.atlassian.com/manage-profile/security/api-tokens)) |
|
|
57
|
-
| `timesheetUrl` | `TIMESHEET_URL` | Full URL to the Kawari timesheet |
|
|
58
|
-
| `timezone` | `TZ` | Must be `Asia/Bangkok` |
|
|
59
|
-
| `linkAudit.projects` | — | Optional Jira project map with `doneStatuses` for `audit-links` |
|
|
26
|
+
Use `workctl jira configure` later if you need to edit Jira credentials, service
|
|
27
|
+
defaults, or other Jira sync settings.
|
|
60
28
|
|
|
61
|
-
|
|
62
|
-
workctl does not load `.env` files. `NO_COLOR=1` disables colored output.
|
|
29
|
+
On macOS and Linux, configuration is stored at:
|
|
63
30
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
and the Playwright Chromium installation.
|
|
67
|
-
|
|
68
|
-
## Commands
|
|
69
|
-
|
|
70
|
-
```
|
|
71
|
-
workctl jira sync [--from YYYY-MM-DD] [--to YYYY-MM-DD] [--export csv|json]
|
|
72
|
-
workctl jira preview [--from YYYY-MM-DD] [--to YYYY-MM-DD] [--export csv|json]
|
|
73
|
-
workctl jira verify [--from YYYY-MM-DD] [--to YYYY-MM-DD] [--export csv|json]
|
|
74
|
-
workctl jira rollback [--from YYYY-MM-DD] [--to YYYY-MM-DD] [--issue KEY] [--dry-run]
|
|
75
|
-
workctl jira audit-links [--from YYYY-MM-DD] [--to YYYY-MM-DD] [--export csv|json]
|
|
76
|
-
workctl jira configure
|
|
77
|
-
workctl jira config show
|
|
78
|
-
workctl jira doctor
|
|
79
|
-
workctl browsers install
|
|
80
|
-
workctl update
|
|
31
|
+
```text
|
|
32
|
+
~/.config/workctl/config.json
|
|
81
33
|
```
|
|
82
34
|
|
|
83
|
-
|
|
84
|
-
`workctl jira configure` is the full editor for Jira-specific settings.
|
|
85
|
-
|
|
86
|
-
| Command | Writes to Jira? | Purpose |
|
|
87
|
-
|---|---|---|
|
|
88
|
-
| `sync` | Yes (with approval) | Full pipeline: scrape, preview, approve, create, verify |
|
|
89
|
-
| `preview` | No | Read-only: scrape and show what would happen |
|
|
90
|
-
| `verify` | No | Compare eligible entries against existing tool-managed Jira worklogs |
|
|
91
|
-
| `rollback` | Yes (typed approval) | Delete matching tool-managed worklogs and restore their time to Remaining Estimate |
|
|
92
|
-
| `audit-links` | No | Audit linked issue statuses for Jira issues found in Kawari |
|
|
93
|
-
| `browsers install` | No | Install the Playwright Chromium browser required by Kawari scraping |
|
|
94
|
-
| `update` | No | Install the latest stable `@geneverse/workctl` release from npm after approval |
|
|
95
|
-
|
|
96
|
-
### Rolling back a sync
|
|
97
|
-
|
|
98
|
-
`workctl jira rollback` reads the selected Kawari entries and previews only Jira
|
|
99
|
-
worklogs carrying matching `jlog:v1` Source Identities. The worklog must belong
|
|
100
|
-
to the current Jira account. Type the displayed `delete N` phrase to proceed,
|
|
101
|
-
or use `--dry-run` for a read-only check.
|
|
102
|
-
|
|
103
|
-
Each deletion sends `adjustEstimate=auto`, so deleting a 2h worklog from an
|
|
104
|
-
issue with 3h remaining restores Remaining Estimate to 5h. The Jira capability does not set
|
|
105
|
-
Original Estimate or an absolute remaining value. Use repeatable
|
|
106
|
-
`--issue OLD-1` options if a source entry's Jira key changed before rollback.
|
|
107
|
-
Once deletion begins, the Jira capability writes a private JSON receipt under
|
|
108
|
-
the local workctl data directory.
|
|
35
|
+
On Windows, it is stored under:
|
|
109
36
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
the current calendar month in `Asia/Bangkok` (showing its inclusive dates) or
|
|
113
|
-
enter custom `From` and `To` dates. The current month is selected by default.
|
|
114
|
-
`preview`, `verify`, and non-interactive commands continue to use the current
|
|
115
|
-
month when dates are omitted. Explicit ranges bypass the prompt and must fall
|
|
116
|
-
within one calendar month.
|
|
117
|
-
|
|
118
|
-
### Auditing linked issue statuses
|
|
119
|
-
|
|
120
|
-
`workctl jira audit-links` reads Jira keys from Kawari for the selected date range. It
|
|
121
|
-
checks links only for source issues whose current status is configured as done
|
|
122
|
-
for that Jira project. Every unique linked pair is reported as `Mismatch` or
|
|
123
|
-
`Aligned`; completed source issues without links are reported as `No Links`.
|
|
124
|
-
Link type and direction are displayed exactly as Jira returns them.
|
|
125
|
-
|
|
126
|
-
Configure the Link Audit Scope with `workctl jira configure`. The wizard reads
|
|
127
|
-
accessible projects and their statuses from Jira, then lets you select the
|
|
128
|
-
Done Statuses for each project:
|
|
129
|
-
|
|
130
|
-
```json
|
|
131
|
-
{
|
|
132
|
-
"version": 1,
|
|
133
|
-
"capabilities": {
|
|
134
|
-
"jira": {
|
|
135
|
-
"linkAudit": {
|
|
136
|
-
"projects": {
|
|
137
|
-
"ABC": {
|
|
138
|
-
"doneStatuses": ["DONE", "READY TO DEPLOY"]
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
}
|
|
37
|
+
```text
|
|
38
|
+
%APPDATA%\workctl\config.json
|
|
145
39
|
```
|
|
146
40
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
the scope are skipped and summarized. Cross-project targets use their own
|
|
150
|
-
configured Done Statuses; targets outside the scope are reported as
|
|
151
|
-
`Not Configured`. Invalid Kawari entries and incomplete Jira responses still
|
|
152
|
-
block the audit. Mismatches do not produce a failing exit code, and the command
|
|
153
|
-
never changes Jira. Use `--export csv|json` to retain the complete report,
|
|
154
|
-
including skipped sources and unconfigured targets.
|
|
155
|
-
|
|
156
|
-
Interactive command output uses one guided terminal presentation for prompts,
|
|
157
|
-
progress, results, and errors. `--help`, `--version`, and non-interactive output
|
|
158
|
-
remain plain text for piping and automation.
|
|
159
|
-
|
|
160
|
-
**Audit export** (`--export`): writes a timestamped CSV or JSON file to the
|
|
161
|
-
local workctl data directory for your records.
|
|
162
|
-
|
|
163
|
-
### Updating workctl
|
|
164
|
-
|
|
165
|
-
Run `workctl update` to check the npm registry for `@geneverse/workctl`. If a
|
|
166
|
-
newer stable version exists, workctl shows the target package, requires you to
|
|
167
|
-
type `yes`, and runs `npm install --global @geneverse/workctl@<version>` without
|
|
168
|
-
`sudo`. This command does not require Jira or Kawari configuration.
|
|
169
|
-
|
|
170
|
-
You can also update directly with npm:
|
|
171
|
-
|
|
172
|
-
```bash
|
|
173
|
-
npm update -g @geneverse/workctl
|
|
174
|
-
```
|
|
175
|
-
|
|
176
|
-
## How It Works
|
|
177
|
-
|
|
178
|
-
### Pipeline
|
|
179
|
-
|
|
180
|
-
Each `sync` runs these steps:
|
|
181
|
-
|
|
182
|
-
1. **Resolve date range** — interactive `sync` offers the displayed current
|
|
183
|
-
month or a custom range before opening Kawari
|
|
184
|
-
2. **Scrape Kawari** — launches a browser; prompts for manual login if the
|
|
185
|
-
session expired
|
|
186
|
-
3. **Classify** — each hours cell becomes a Timesheet Entry and is classified as:
|
|
187
|
-
- **Eligible** — exactly one Jira issue key, ready to sync
|
|
188
|
-
- **Unmapped** — no Jira key (e.g. internal meetings), skipped with a warning
|
|
189
|
-
- **Invalid** — bad data, multiple keys, or ambiguous identity
|
|
190
|
-
4. **Read Jira and repair keys** — fetches existing worklogs to check for prior
|
|
191
|
-
syncs. If a Jira issue does not exist, an interactive run can replace that
|
|
192
|
-
key for the current batch and validate the replacement immediately.
|
|
193
|
-
5. **Preview** — shows what will be created, skipped, or flagged as a conflict
|
|
194
|
-
6. **Approve** — interactive confirmation before any writes
|
|
195
|
-
7. **Create worklogs** — each new worklog gets a `jlog:v1:` marker in its
|
|
196
|
-
comment
|
|
197
|
-
8. **Verify** — re-reads Jira to confirm every expected worklog exists
|
|
198
|
-
|
|
199
|
-
`audit-links` shares date selection, Kawari classification, and temporary
|
|
200
|
-
missing-key repair, but reads Jira link metadata through a separate read-only
|
|
201
|
-
pipeline and never creates or transitions issues.
|
|
41
|
+
The Jira API token is stored as plain text in that user config file. Use
|
|
42
|
+
`workctl` only on a trusted personal workstation.
|
|
202
43
|
|
|
203
|
-
|
|
44
|
+
Environment variables override config file values field by field:
|
|
204
45
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
46
|
+
| Config field | Environment override |
|
|
47
|
+
|---|---|
|
|
48
|
+
| `jiraBaseUrl` | `JIRA_BASE_URL` |
|
|
49
|
+
| `jiraEmail` | `JIRA_EMAIL` |
|
|
50
|
+
| `jiraApiToken` | `JIRA_API_TOKEN` |
|
|
51
|
+
| `timesheetUrl` | `TIMESHEET_URL` |
|
|
52
|
+
| `timezone` | `TZ` |
|
|
212
53
|
|
|
213
|
-
|
|
54
|
+
`workctl` does not load `.env` files. Use `workctl jira config show` to inspect
|
|
55
|
+
effective values and where they came from. The token is always redacted.
|
|
214
56
|
|
|
215
|
-
|
|
216
|
-
snapshot of the source entry. On re-runs, entries with a matching marker are
|
|
217
|
-
skipped automatically. The marker survives local state loss and prevents
|
|
218
|
-
duplicates across machines.
|
|
219
|
-
|
|
220
|
-
## Example
|
|
221
|
-
|
|
222
|
-
```
|
|
223
|
-
$ workctl jira sync --from 2026-01-05 --to 2026-01-09
|
|
224
|
-
|
|
225
|
-
──────────────────────────────────────────────────
|
|
226
|
-
Sync Batch: 2026-01-05 → 2026-01-09
|
|
227
|
-
──────────────────────────────────────────────────
|
|
228
|
-
|
|
229
|
-
╔═══════════════════════════════════════════════════════╗
|
|
230
|
-
║ PREVIEW ║
|
|
231
|
-
╠═══════════════════════════════════════════════════════╣
|
|
232
|
-
║ Create 3 worklog(s) 12.0h ║
|
|
233
|
-
║ Skip 1 worklog(s) 2.0h ║
|
|
234
|
-
╠═══════════════════════════════════════════════════════╣
|
|
235
|
-
║ Total eligible 14.0h ║
|
|
236
|
-
╚═══════════════════════════════════════════════════════╝
|
|
237
|
-
|
|
238
|
-
Create 3 Jira worklog(s) totaling 12h? Yes
|
|
239
|
-
|
|
240
|
-
◇ Ownership rechecked
|
|
241
|
-
│ ╭───────────────────────────────────────────────────╮
|
|
242
|
-
│ │ PROGRESS DATE ISSUE TIME STATUS │
|
|
243
|
-
│ ├───────────────────────────────────────────────────┤
|
|
244
|
-
✓ │ 1/3 2026-01-07 PROJ-123 4h Created │
|
|
245
|
-
✓ │ 2/3 2026-01-08 PROJ-456 4h Created │
|
|
246
|
-
✓ │ 3/3 2026-01-09 PROJ-789 4h Created │
|
|
247
|
-
│ ╰───────────────────────────────────────────────────╯
|
|
248
|
-
● Created 3 (12h) · Failed 0 (0h)
|
|
249
|
-
|
|
250
|
-
Verified: 3 of 3 expected worklogs found on Jira.
|
|
251
|
-
```
|
|
252
|
-
|
|
253
|
-
## Development
|
|
254
|
-
|
|
255
|
-
**Prerequisites:** Node.js ≥22, npm, a Jira Cloud API token, and access to the
|
|
256
|
-
Kawari timesheet.
|
|
257
|
-
|
|
258
|
-
For a fresh clone, bootstrap the project once. This installs npm dependencies
|
|
259
|
-
and Playwright Chromium, then opens the onboarding hub:
|
|
260
|
-
|
|
261
|
-
```bash
|
|
262
|
-
npm run bootstrap
|
|
263
|
-
```
|
|
264
|
-
|
|
265
|
-
Run the CLI directly from TypeScript without building or linking it:
|
|
266
|
-
|
|
267
|
-
```bash
|
|
268
|
-
npm run dev -- jira sync
|
|
269
|
-
npm run dev -- jira preview --from 2026-07-01 --to 2026-07-04
|
|
270
|
-
```
|
|
57
|
+
## Commands
|
|
271
58
|
|
|
272
|
-
|
|
59
|
+
| Command | Purpose |
|
|
60
|
+
|---|---|
|
|
61
|
+
| `workctl setup` | Configure and verify Jira sync |
|
|
62
|
+
| `workctl browsers install` | Install the Playwright Chromium browser used for Kawari scraping |
|
|
63
|
+
| `workctl jira preview [--from YYYY-MM-DD] [--to YYYY-MM-DD]` | Show what would be synced without writing to Jira |
|
|
64
|
+
| `workctl jira sync [--from YYYY-MM-DD] [--to YYYY-MM-DD]` | Scrape Kawari, preview, ask for approval, create Jira worklogs, and verify them |
|
|
65
|
+
| `workctl jira doctor` | Check config, Jira credentials, permissions, and browser installation |
|
|
66
|
+
| `workctl jira rollback [--from YYYY-MM-DD] [--to YYYY-MM-DD] [--issue KEY] [--dry-run]` | Delete matching tool-managed worklogs after typed approval |
|
|
67
|
+
| `workctl update` | Update the global `@geneverse/workctl` install after approval |
|
|
273
68
|
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
npm run build
|
|
277
|
-
npm link
|
|
278
|
-
workctl jira sync
|
|
279
|
-
```
|
|
69
|
+
When dates are omitted, Jira sync uses the current calendar month in
|
|
70
|
+
`Asia/Bangkok`. Explicit date ranges must stay within one calendar month.
|
|
280
71
|
|
|
281
|
-
|
|
72
|
+
## Updating
|
|
282
73
|
|
|
283
74
|
```bash
|
|
284
|
-
|
|
285
|
-
npm run typecheck # type-check only, no emit
|
|
286
|
-
npm run build # compile TypeScript → dist/
|
|
287
|
-
npm run test:package # pack and install the CLI in a temporary npm prefix
|
|
75
|
+
workctl update
|
|
288
76
|
```
|
|
289
77
|
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
Start from a clean `main` branch, then run the development checks before
|
|
293
|
-
creating a patch release:
|
|
78
|
+
You can also update directly with npm:
|
|
294
79
|
|
|
295
80
|
```bash
|
|
296
|
-
npm
|
|
297
|
-
npm run typecheck
|
|
298
|
-
npm run build
|
|
299
|
-
npm run test:package
|
|
300
|
-
npm version patch -m "chore(release): %s"
|
|
301
|
-
git push origin main --follow-tags
|
|
302
|
-
```
|
|
303
|
-
|
|
304
|
-
`npm version` updates `package.json` and `package-lock.json`, creates the
|
|
305
|
-
release commit, and tags it as `v<version>`. The tag workflow publishes
|
|
306
|
-
`@geneverse/workctl` to the npm registry with public access.
|
|
307
|
-
|
|
308
|
-
### Project Structure
|
|
309
|
-
|
|
310
|
-
```
|
|
311
|
-
packages/
|
|
312
|
-
├── cli/ workctl composition root and binary
|
|
313
|
-
└── capabilities/
|
|
314
|
-
├── jira/ Kawari-to-Jira time synchronization
|
|
315
|
-
├── jenkins/ Git-backed Jenkins definitions
|
|
316
|
-
└── assistant/ vendor CLI installation status
|
|
81
|
+
npm update -g @geneverse/workctl
|
|
317
82
|
```
|
|
318
83
|
|
|
319
|
-
|
|
320
|
-
domain glossary. Capabilities are built into one release and cannot import one
|
|
321
|
-
another. The CLI imports only their public entrypoints.
|
|
322
|
-
|
|
323
|
-
### Local State
|
|
324
|
-
|
|
325
|
-
Runtime data is user-global. On macOS and Linux it lives under
|
|
326
|
-
`~/.local/share/workctl/jira/`; on Windows it lives under
|
|
327
|
-
`%LOCALAPPDATA%\workctl\jira\`:
|
|
328
|
-
|
|
329
|
-
- `browser-profile/` — persistent Playwright Chromium session
|
|
330
|
-
- `audit-exports/` — timestamped CSV/JSON exports
|
|
331
|
-
- `state/` — sync state
|
|
332
|
-
|
|
333
|
-
Run `workctl setup` after installation; the first sync will require Kawari
|
|
334
|
-
login.
|
|
335
|
-
|
|
336
|
-
Uninstall the CLI with npm:
|
|
84
|
+
## Uninstall
|
|
337
85
|
|
|
338
86
|
```bash
|
|
339
87
|
npm uninstall -g @geneverse/workctl
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// Generated from the root package.json by scripts/build.mjs.
|
|
2
|
-
export const RELEASE_VERSION = "0.2.
|
|
2
|
+
export const RELEASE_VERSION = "0.2.10";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@geneverse/workctl",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.10",
|
|
4
4
|
"description": "Deterministic internal developer-workflow CLI",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -34,7 +34,8 @@
|
|
|
34
34
|
"node": ">=22"
|
|
35
35
|
},
|
|
36
36
|
"scripts": {
|
|
37
|
-
"bootstrap": "npm ci &&
|
|
37
|
+
"bootstrap": "npm ci && npm run browsers:install && npm run dev -- setup",
|
|
38
|
+
"browsers:install": "playwright install --with-deps chromium",
|
|
38
39
|
"build": "node scripts/build.mjs",
|
|
39
40
|
"dev": "tsx packages/cli/src/bin.ts",
|
|
40
41
|
"test": "vitest run",
|