logwork-cli 0.0.0-stage → 1.0.0

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.
Files changed (91) hide show
  1. package/LICENSE +11 -0
  2. package/README.md +287 -2
  3. package/RELEASE.md +89 -0
  4. package/bin/logwork.mjs +101 -0
  5. package/commands/auth.mjs +227 -0
  6. package/commands/delete.mjs +69 -0
  7. package/commands/doctor.mjs +24 -0
  8. package/commands/edit.mjs +88 -0
  9. package/commands/history.mjs +62 -0
  10. package/commands/query.mjs +52 -0
  11. package/commands/quick.mjs +163 -0
  12. package/commands/reconcile.mjs +55 -0
  13. package/commands/release.mjs +77 -0
  14. package/commands/reminder.mjs +172 -0
  15. package/commands/setup.mjs +504 -0
  16. package/commands/tui.mjs +50 -0
  17. package/commands/update.mjs +161 -0
  18. package/docs/advanced.md +334 -0
  19. package/docs/mcp-setup.md +347 -0
  20. package/docs/operations-guide.md +587 -0
  21. package/docs/recipes.md +259 -0
  22. package/docs/security.md +151 -0
  23. package/examples/mcp/antigravity.mcp_config.json +8 -0
  24. package/examples/mcp/codex.config.toml +5 -0
  25. package/examples/mcp/copilot.mcp.json +9 -0
  26. package/lib/api-auth.mjs +1259 -0
  27. package/lib/api.mjs +1422 -0
  28. package/lib/apply-ledger.mjs +227 -0
  29. package/lib/atomic-file.mjs +24 -0
  30. package/lib/auth-diagnostics.mjs +113 -0
  31. package/lib/auth-errors.mjs +22 -0
  32. package/lib/auth-redaction.mjs +78 -0
  33. package/lib/auth-terminal.mjs +97 -0
  34. package/lib/auth.mjs +323 -0
  35. package/lib/batch-parser.mjs +145 -0
  36. package/lib/batch-workflow.mjs +842 -0
  37. package/lib/config.mjs +191 -0
  38. package/lib/credential-store.mjs +130 -0
  39. package/lib/diagnostics.mjs +307 -0
  40. package/lib/entrypoint.mjs +14 -0
  41. package/lib/file-lock.mjs +44 -0
  42. package/lib/http.mjs +125 -0
  43. package/lib/jira-api.mjs +258 -0
  44. package/lib/jira-auth.mjs +203 -0
  45. package/lib/jira-workflow.mjs +523 -0
  46. package/lib/keychain.mjs +105 -0
  47. package/lib/legacy-migration.mjs +66 -0
  48. package/lib/list-navigation.mjs +19 -0
  49. package/lib/logwork-config.mjs +199 -0
  50. package/lib/logwork-f03-enrich.mjs +41 -0
  51. package/lib/macos.mjs +33 -0
  52. package/lib/manual-apply-state.mjs +35 -0
  53. package/lib/manual-commands.mjs +294 -0
  54. package/lib/manual-drafts.mjs +154 -0
  55. package/lib/manual-ink-app.mjs +1654 -0
  56. package/lib/manual-ink-auth.mjs +349 -0
  57. package/lib/manual-ink-ui.mjs +675 -0
  58. package/lib/manual-input.mjs +21 -0
  59. package/lib/manual-logwork-wizard.mjs +310 -0
  60. package/lib/manual-mcp.mjs +187 -0
  61. package/lib/manual-repl.mjs +1037 -0
  62. package/lib/manual-targets.mjs +78 -0
  63. package/lib/mcp-server.mjs +793 -0
  64. package/lib/os-notification.mjs +105 -0
  65. package/lib/package-info.mjs +17 -0
  66. package/lib/paths.mjs +68 -0
  67. package/lib/project-identity.mjs +66 -0
  68. package/lib/project-mapping-workflow.mjs +309 -0
  69. package/lib/project-resolver.mjs +373 -0
  70. package/lib/query-workflow.mjs +553 -0
  71. package/lib/reconciliation-workflow.mjs +446 -0
  72. package/lib/release-doctor.mjs +448 -0
  73. package/lib/reminder-config.mjs +71 -0
  74. package/lib/reminder-scheduler.mjs +301 -0
  75. package/lib/reminder-service.mjs +118 -0
  76. package/lib/reminder-state.mjs +38 -0
  77. package/lib/reminder-workflow.mjs +299 -0
  78. package/lib/ro-delete-args.mjs +38 -0
  79. package/lib/ro-delete-workflow.mjs +115 -0
  80. package/lib/ro-edit-args.mjs +142 -0
  81. package/lib/ro-edit-workflow.mjs +632 -0
  82. package/lib/ro-entry-reader.mjs +56 -0
  83. package/lib/ro-resubmit-workflow.mjs +134 -0
  84. package/lib/terminal-auth-prompts.mjs +120 -0
  85. package/lib/ui.mjs +133 -0
  86. package/lib/update-service.mjs +350 -0
  87. package/lib/util.mjs +66 -0
  88. package/lib/windows-credential-manager.mjs +260 -0
  89. package/lib/worklog-task-resolver.mjs +113 -0
  90. package/package.json +72 -4
  91. package/setup.sh +22 -0
package/LICENSE ADDED
@@ -0,0 +1,11 @@
1
+ Proprietary License
2
+
3
+ Copyright (c) 2026 Truc Tran and contributors.
4
+ All rights reserved.
5
+
6
+ This project is proprietary and is not open source. Use, copying,
7
+ modification, distribution, publication, sublicensing, or sale of this
8
+ software or its documentation is permitted only with prior written permission
9
+ from the copyright holder or under a separate written agreement.
10
+
11
+ No license is granted by implication, estoppel, or otherwise.
package/README.md CHANGED
@@ -1,3 +1,288 @@
1
- # Temporary Holding Version
1
+ # logwork-cli
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ [npm version](https://www.npmjs.com/package/logwork-cli)
4
+ [license](LICENSE)
5
+
6
+ Log work to Resource Optimiser (RO) and self-hosted Jira from the terminal, from an MCP server for AI IDEs, or from a terminal UI.
7
+
8
+ One command, `logwork`, covers everything:
9
+
10
+ - `logwork`: the terminal UI.
11
+ - `logwork <command>`: one-shot commands such as `logwork query this-week` or `logwork edit 304032 --task "Bug Fix"`.
12
+ - `logwork mcp`: the MCP server that Cursor, Codex, Google Antigravity, GitHub Copilot / VS Code and Claude Code connect to.
13
+
14
+ Credentials stay local. Resource Optimiser passwords and 2FA codes, and Jira Personal Access Tokens, are entered in the terminal only. They never go into MCP config or AI chat.
15
+
16
+ ## Install
17
+
18
+ Requirements: macOS or Windows 10/11, Node.js 22+, npm.
19
+
20
+ ```bash
21
+ npm install -g logwork-cli
22
+ logwork setup
23
+ ```
24
+
25
+ `logwork setup` does the following:
26
+ - installs the runtime to `~/.logwork-cli` (`%USERPROFILE%\.logwork-cli` on Windows),
27
+ - links the `logwork` command,
28
+ - offers to log in,
29
+ - prints copy-ready MCP configs that use your real local path.
30
+
31
+ ## Upgrading from logwork-helper
32
+
33
+ The package was renamed from `logwork-helper` to `logwork-cli`, and the `logwork-helper` command no longer exists. To upgrade:
34
+
35
+ ```bash
36
+ npm install -g logwork-cli
37
+ logwork setup
38
+ ```
39
+
40
+ Most of the move is automatic:
41
+
42
+ - **Old global package:** `logwork setup` removes the global `logwork-helper` package, so its `logwork` command does not conflict with the new one.
43
+ - **Local state:** on the first run, settings, project mappings, drafts, apply history and the reminder config are copied from `~/.logwork-helper` to `~/.logwork-cli`. The old directory is left in place.
44
+ - **Login sessions:** your RO and Jira sessions are copied from the old Keychain / Credential Manager entry (`logwork-helper`) to the new one (`logwork-cli`), so you do not need to log in again.
45
+ - **Repo mappings:** a repo that has `.logwork-helper.json` keeps using it until a `.logwork.json` exists.
46
+ - **Reminder:** an enabled reminder is re-registered by `logwork setup`, and the old OS schedule is removed.
47
+
48
+ Two things you need to do yourself:
49
+
50
+ - **IDE config:** replace the old `logwork-helper` MCP entry with the new `logwork` entry printed by `logwork setup` or `/mcp`.
51
+ - **MCP tool names:** the tool names changed. See the [old → new tool name table](docs/mcp-setup.md#tool-name-changes-from-logwork-helper).
52
+
53
+ ## Log In
54
+
55
+ ```bash
56
+ logwork login # Resource Optimiser: email, password, 2FA in this terminal
57
+ logwork login jira # Jira Personal Access Token
58
+ logwork login jira --base-url https://jira.example.com
59
+ logwork status # RO and Jira status, never prints tokens
60
+ logwork logout [ro|jira]
61
+ ```
62
+
63
+ Sessions are stored in macOS Keychain or Windows Credential Manager. The default Jira URL is `https://jira-vnv.vinova.sg`.
64
+
65
+ ## Commands
66
+
67
+ ```text
68
+ logwork Open the terminal UI
69
+ logwork query [period] Booked vs logged hours with entry ids (today, yesterday, this-week, last-week, this-month, last-month)
70
+ logwork quick [-m text] Log one entry for today with guided prompts
71
+ logwork edit <id> ... Change an existing RO entry (replaces it)
72
+ logwork delete <id> Delete a submitted or approved RO entry
73
+ logwork reconcile Compare RO and Jira hours by day (read-only)
74
+ logwork history Local apply history
75
+ logwork login|logout|status [ro|jira]
76
+ logwork setup Install the runtime and print MCP configs
77
+ logwork mcp Run the MCP stdio server (used by IDE configs)
78
+ logwork reminder ... Weekday logwork reminder
79
+ logwork update ... Check for or install a new version
80
+ logwork doctor Write a sanitized diagnostics report
81
+ ```
82
+
83
+ Add `--help` to any command for its options.
84
+
85
+ ## Logwork Line Format
86
+
87
+ Every Resource Optimiser entry has a **worklog task** and a free-text **description**. The worklog task is an RO catalog item such as `Feature Development` or `Code Review & Refactoring`. Write each line as:
88
+
89
+ ```text
90
+ Monday, 01 Jun 2026
91
+ +2 Feature Development | Implement maintenance mode management and status UI (SCB-213)
92
+ +1 Code Review & Refactoring | Review system page PR (SCB-214)
93
+ ```
94
+
95
+ - **Before `|`:** the RO worklog task name, or `#<id>`. MCP clients can list valid names with `list_tasks`.
96
+ - **After `|`:** the description saved on the RO entry. Jira uses it as the worklog comment.
97
+ - **Lines without `|`:** these still work in two cases. If the whole text is a catalog task name, the entry is saved with no description and a warning. If the assistant passes `defaultWorklogTask`, that task is used and the text becomes the description.
98
+
99
+ The default tasks shared by all projects are:
100
+
101
+ | id | Task | type_of_work |
102
+ |---|---|---|
103
+ | 71 | Feature Development | create |
104
+ | 74 | Bug Fix | correct |
105
+ | 182 | Code Review & Refactoring | improve |
106
+ | 79 | Deployment & Release | create |
107
+ | 181 | Requirements & Design | create |
108
+ | 183 | Testing Activities | create |
109
+ | 111 | Other Activities | other |
110
+
111
+ ## API Notes
112
+
113
+ - Read bookings: `GET /member-logtime/timesheet`
114
+ - Read worklog tasks: `GET /logwork/tasks?project_id=<id>` and `GET /logwork/tasks/defaults?project_id=<id>`
115
+ - Write an entry: `POST /logwork/entries`
116
+ - Delete an entry: `DELETE /logwork/entries/:id`
117
+ - Resubmit a rejected entry: `PATCH /logwork/entries/:id/resubmit`
118
+
119
+ ```json
120
+ {
121
+ "worklog_task_id": 71,
122
+ "type_of_work": "create",
123
+ "effort_hours": 2,
124
+ "logdate": "2026-06-01",
125
+ "project_id": 720,
126
+ "description": "Implement maintenance mode management and status UI (SCB-213)"
127
+ }
128
+ ```
129
+
130
+ `project_id` is sent only when the worklog task is a shared default task.
131
+
132
+ ## Set Up MCP
133
+
134
+ `logwork setup` prints the configs. You can also open the terminal UI with `logwork` and type `/mcp` (or `/mcp cursor`, `/mcp antigravity`, `/mcp copilot`, `/mcp claude-code`, `/mcp codex`).
135
+
136
+ Every client runs the same thing, `node ~/.logwork-cli/bin/logwork.mjs mcp`, under the server name `logwork`:
137
+
138
+ ```json
139
+ {
140
+ "mcpServers": {
141
+ "logwork": {
142
+ "command": "node",
143
+ "args": ["/Users/you/.logwork-cli/bin/logwork.mjs", "mcp"]
144
+ }
145
+ }
146
+ }
147
+ ```
148
+
149
+ For Claude Code, run:
150
+
151
+ ```bash
152
+ claude mcp add --transport stdio logwork -- node ~/.logwork-cli/bin/logwork.mjs mcp
153
+ ```
154
+
155
+ Restart or reload the IDE's MCP tools after saving.
156
+
157
+ The server exposes 15 tools. It also sends `instructions` covering the approval rules, the line format and the recommended call order. Every write is **two calls to the same tool**:
158
+ 1. Call the tool without `confirm`. It returns a preview with a `batchId` or `previewId` and a summary.
159
+ 2. After the user approves, call the same tool again with only that id and `confirm: true`.
160
+
161
+ See [docs/mcp-setup.md](docs/mcp-setup.md#exposed-tools) for the tool table.
162
+
163
+ Verify from your assistant:
164
+
165
+ ```text
166
+ Check my logwork for this week.
167
+ ```
168
+
169
+ ## Edit Existing RO Logwork
170
+
171
+ Get the entry id from `logwork query` (or `get_logwork` in MCP), then:
172
+
173
+ ```bash
174
+ logwork edit 304032 --hours 0.5
175
+ logwork edit 304032 --desc "Fix date picker timezone (SAP-42)"
176
+ logwork edit 304032 --task "Bug Fix" --desc "Fix date picker timezone (SAP-42)"
177
+ logwork edit 304032 --task "#74" --type correct
178
+ ```
179
+
180
+ Options:
181
+ - `--hours`
182
+ - `--task`: a worklog task from the project catalog, or `#<id>`.
183
+ - `--desc`
184
+ - `--type`: `create`, `correct`, `improve` or `other`. When the task changes and `--type` is omitted, the new task's catalog type is used.
185
+
186
+ The long forms `--task-name` and `--description` also work. Project and date are always preserved.
187
+
188
+ Resource Optimiser has no staff API for editing an entry; the edit endpoint is PM-only. So apply **replaces** the entry:
189
+
190
+ 1. It re-reads the entry and stops if the entry changed after the preview.
191
+ 2. It creates the corrected entry with `POST /logwork/entries`.
192
+ 3. It deletes the original with `DELETE /logwork/entries/:id`.
193
+ 4. It verifies the new entry.
194
+
195
+ If the create fails, the original is untouched. If the delete fails, the new entry is deleted again, so nothing changes.
196
+
197
+ Deleting on RO needs no approval, and a correctly formatted new entry is approved immediately, so the edit takes effect at once. The new entry gets a **new logwork id**.
198
+
199
+ Some entries cannot be edited this way:
200
+ - Only `submitted` or `approved` entries can be edited.
201
+ - Rejected entries are fixed with `resubmit_entry`.
202
+ - Entries on locked days, entries created by Jira, and entries owned by another user are blocked.
203
+
204
+ The CLI previews the diff and asks for confirmation. Use `--yes` for an already reviewed non-interactive command.
205
+
206
+ In the terminal UI: `/edit-logwork 304032 --task Bug Fix --desc Fix date picker timezone (SAP-42)`.
207
+
208
+ In MCP, call `edit_entry` with `logworkId` and the changes, show the summary, then call `edit_entry` with `previewId` and `confirm: true`. The result returns `originalLogworkId` and `newLogworkId`.
209
+
210
+ ## Daily Use
211
+
212
+ Ask your assistant:
213
+
214
+ ```text
215
+ Check whether I have logged anything today.
216
+ ```
217
+
218
+ ```text
219
+ Preview this logwork and ask for my approval before submitting:
220
+ Monday, 01 Jun 2026
221
+ +2 Feature Development | Maintenance mode management and status UI (SCB-213)
222
+ ```
223
+
224
+ ```text
225
+ Set up the SCB ticket mapping to project 2621A-SIT-HTML BUILDER-PRJ.
226
+ ```
227
+
228
+ From the terminal:
229
+
230
+ ```bash
231
+ logwork quick -m "Fix login bug (SCB-12)" # one entry for today
232
+ logwork # terminal UI
233
+ ```
234
+
235
+ In the terminal UI, `/logwork` opens a target picker. `/logwork ro` writes Resource Optimiser entries, `/logwork jira` writes Jira worklogs, and `/logwork both` previews and applies both with separate approvals. Type `/` to see every command, for example:
236
+ - `/query this-week`
237
+ - `/reconcile`
238
+ - `/projects`
239
+ - `/map SCB 5234`
240
+ - `/history`
241
+ - `/diagnostics`
242
+
243
+ ## Reminder
244
+
245
+ ```bash
246
+ logwork reminder enable # 17:00 Monday-Friday, RO and Jira
247
+ logwork reminder enable --time 18:00 --target ro
248
+ logwork reminder test
249
+ logwork reminder status
250
+ logwork reminder disable
251
+ ```
252
+
253
+ For Resource Optimiser, the reminder compares today's logged and booked hours. For Jira, it checks whether you have any worklog today. Complete days stay silent.
254
+
255
+ macOS uses a user `launchd` agent (`sg.vinova.logwork-cli.reminder`) and Windows uses Task Scheduler (`Logwork Reminder`). Neither schedule stores credentials.
256
+
257
+ ## Reconcile RO And Jira
258
+
259
+ ```bash
260
+ logwork reconcile this-week
261
+ logwork reconcile last-month --json
262
+ ```
263
+
264
+ This is read-only. It shows booked, RO and Jira hours by day and flags mismatches. A correction suggestion is included only when an RO entry contains exactly one Jira issue key. Applying a suggestion still goes through the normal preview and approval flow. MCP clients use the `reconcile` tool.
265
+
266
+ ## Update
267
+
268
+ ```bash
269
+ logwork update check
270
+ logwork update install
271
+ ```
272
+
273
+ The terminal UI shows a short notice when a newer release is available. Checks are cached for 24 hours, and network errors never block logwork.
274
+
275
+ Updating keeps OS credentials, project mappings, drafts and apply history. Reconnect MCP clients after an update.
276
+
277
+ ## More Docs
278
+
279
+ - [Operations guide](docs/operations-guide.md): CLI/MCP feature map, RO/Jira/Both processing, mapping, reconciliation, history, reminders, updates and OS validation.
280
+ - [MCP setup](docs/mcp-setup.md): client configs, the tool table, the old → new tool names, and common workflows.
281
+ - [Security and auth](docs/security.md): Keycloak flow, Jira PAT flow, OS credential storage, stored files and the safety model.
282
+ - [Advanced usage](docs/advanced.md): environment overrides, terminal UI details, troubleshooting and release checks.
283
+ - [Quick recipes](docs/recipes.md): copy-ready workflows.
284
+ - [Release checklist](RELEASE.md).
285
+
286
+ ## License
287
+
288
+ This project is proprietary and not open source. See [LICENSE](LICENSE).
package/RELEASE.md ADDED
@@ -0,0 +1,89 @@
1
+ # Release Checklist
2
+
3
+ Use this checklist before publishing or tagging a production release.
4
+
5
+ The complete end-user update and maintainer publish flows are documented in the [integrated operations guide](docs/operations-guide.md).
6
+
7
+ ## Version And Publish Sequence
8
+
9
+ Publishing is automated. Pushing a version bump to `main` is the release:
10
+
11
+ ```bash
12
+ # 1. Add "## [<version>] - <date>" with a ### Summary to CHANGELOG.md
13
+ npm version <version> --no-git-tag-version
14
+ npm run release:check
15
+ git add -A
16
+ git commit -m "release v<version>"
17
+ git push origin main
18
+ ```
19
+
20
+ After CI passes on `main`, `.github/workflows/release.yml`:
21
+
22
+ 1. reads the version from `package.json`;
23
+ 2. publishes `logwork-cli@<version>` to npm with provenance, using the `NPM_TOKEN` repository secret (skipped if already published);
24
+ 3. creates tag `v<version>` and a GitHub Release whose description is the `CHANGELOG.md` section (skipped if the tag exists).
25
+
26
+ Check the result:
27
+
28
+ ```bash
29
+ gh run list --workflow Release --limit 3
30
+ npm view logwork-cli version
31
+ gh release view v<version>
32
+ ```
33
+
34
+ To retry a failed release, re-run the Release workflow (or `gh workflow run Release`). Use `minor` or `major` instead of `patch` when required by SemVer. Never reuse an already published version.
35
+
36
+ ### npm token
37
+
38
+ The workflow uses the `NPM_TOKEN` repository secret (an npm automation or granular token with publish rights to `logwork-cli`). Set or rotate it with `gh secret set NPM_TOKEN --repo malcohelper/logwork-cli` and paste the token at the prompt. Never put the token in files, commits or command arguments. Preferred long term: configure npm Trusted Publishing for this repo and workflow on npmjs.com, then delete the secret; `npm publish --provenance` in the workflow already runs with `id-token: write`.
39
+
40
+ ## Required Gates
41
+
42
+ Run the local release gate:
43
+
44
+ ```bash
45
+ npm run release:check
46
+ ```
47
+
48
+ Before publishing, run the release preflight doctor:
49
+
50
+ ```bash
51
+ logwork release doctor --full
52
+ ```
53
+
54
+ This checks version consistency, git cleanliness, npm auth, npm latest version, GitHub auth, tag/release state, local tarball artifacts, tests, audit, pack dry-run, and diff whitespace.
55
+
56
+ The gate must pass all of the following:
57
+
58
+ - `npm test`
59
+ - `npm audit --omit=dev --audit-level=moderate`
60
+ - `npm pack --dry-run`
61
+ - `git diff --check`
62
+
63
+ ## Manual Verification
64
+
65
+ - Install from the packed tarball in a temporary directory.
66
+ - Run `logwork setup --no-login`.
67
+ - Confirm the printed MCP config uses server name `logwork` and `node ~/.logwork-cli/bin/logwork.mjs mcp`.
68
+ - Run `logwork --help` and `logwork --version`.
69
+ - Run `logwork update check --force` against the published npm version.
70
+ - Run `logwork mcp` through an MCP client smoke test and confirm it lists the 15 tools (`get_logwork`, `list_projects`, `list_tasks`, `log_work`, `edit_entry`, `resubmit_entry`, `delete_entry`, `log_jira_work`, `get_jira_issue`, `reconcile`, `get_history`, `map_project`, `login`, `reminder`, `update`).
71
+ - Confirm the `update` tool requires `confirm: true` for `action: "install"`, and `reconcile` takes preset periods only with no credential or confirmation fields.
72
+ - Run `logwork reconcile this-week` and confirm it reports RO/Jira daily totals without writing either system.
73
+ - On a machine with an older `logwork-helper` install, confirm the first run copies state to `~/.logwork-cli` and `logwork status` shows the existing session without a new login.
74
+ - Confirm the Windows CI job passes the dedicated `Verify Windows Credential Manager integration` step.
75
+ - Run `logwork reminder test`, confirm a native notification appears, then verify `logwork reminder status` and clean up with `logwork reminder disable`.
76
+ - Run `logwork status` and confirm no token is printed.
77
+
78
+ ## Safety Checks
79
+
80
+ - Do not include Resource Optimiser tokens, `.env` files, diagnostics reports, or machine-specific MCP configs in the package.
81
+ - Confirm `logwork --version` and the MCP server version match `package.json`.
82
+ - Confirm `README.md` and onboarding output describe the same primary setup flow.
83
+ - Confirm no untracked release artifacts are included except intentional documentation.
84
+
85
+ ## Rollback
86
+
87
+ - Keep the previous npm package version available.
88
+ - If a release introduces auth, MCP, or apply-path regressions, roll back by instructing users to install the previous known-good npm version.
89
+ - Do not publish a replacement with the same version; publish a new patch version after the fix is verified.
@@ -0,0 +1,101 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { isMainModule } from '../lib/entrypoint.mjs';
4
+ import { migrateLegacyHome } from '../lib/legacy-migration.mjs';
5
+ import { readPackageVersion } from '../lib/package-info.mjs';
6
+
7
+ // One entry point for every surface:
8
+ // logwork -> terminal UI
9
+ // logwork <command> ... -> CLI command (loaded on demand, run in-process)
10
+ // logwork mcp -> MCP stdio server for IDEs and agent CLIs
11
+ export const COMMANDS = [
12
+ { name: 'query', usage: 'query [today|yesterday|this-week|last-week|this-month|last-month] [--json]', summary: 'Show booked vs logged hours with entry ids', load: () => import('../commands/query.mjs'), fn: 'run' },
13
+ { name: 'quick', usage: 'quick [-m "what you did"]', summary: 'Log one entry for today with guided prompts', load: () => import('../commands/quick.mjs'), fn: 'run' },
14
+ { name: 'edit', usage: 'edit <id> [--hours h] [--task name|#id] [--desc text] [--type type]', summary: 'Change an existing RO entry (replaces it)', load: () => import('../commands/edit.mjs'), fn: 'runRoEditCommand' },
15
+ { name: 'delete', usage: 'delete <id>', summary: 'Delete a submitted or approved RO entry', load: () => import('../commands/delete.mjs'), fn: 'runRoDeleteCommand' },
16
+ { name: 'reconcile', usage: 'reconcile [period] [--json]', summary: 'Compare RO and Jira hours by day', load: () => import('../commands/reconcile.mjs'), fn: 'runReconcileCommand' },
17
+ { name: 'history', usage: 'history [--target ro|jira|both] [--limit n] [--json]', summary: 'Show the local apply history', load: () => import('../commands/history.mjs'), fn: 'runHistoryCommand' },
18
+ { name: 'login', usage: 'login [ro|jira] [--base-url url]', summary: 'Log in to Resource Optimiser (default) or Jira', load: () => import('../commands/auth.mjs'), fn: 'runLogin' },
19
+ { name: 'logout', usage: 'logout [ro|jira]', summary: 'Remove the stored RO (default) or Jira session', load: () => import('../commands/auth.mjs'), fn: 'runLogout' },
20
+ { name: 'status', usage: 'status', summary: 'Show RO and Jira login status', load: () => import('../commands/auth.mjs'), fn: 'runStatus' },
21
+ { name: 'setup', usage: 'setup [--login|--no-login]', summary: 'Install the runtime and print MCP configs', load: () => import('../commands/setup.mjs'), fn: 'run' },
22
+ { name: 'mcp', usage: 'mcp', summary: 'Run the MCP stdio server (used by IDE configs)', load: () => import('../lib/mcp-server.mjs'), fn: 'startMcpServer' },
23
+ { name: 'reminder', usage: 'reminder enable|disable|status|test', summary: 'Manage the weekday logwork reminder', load: () => import('../commands/reminder.mjs'), fn: 'runReminderCli' },
24
+ { name: 'update', usage: 'update [check|install]', summary: 'Check for or install a new version', load: () => import('../commands/update.mjs'), fn: 'runUpdateCli' },
25
+ { name: 'doctor', usage: 'doctor', summary: 'Write a sanitized diagnostics report', load: () => import('../commands/doctor.mjs'), fn: 'run' },
26
+ { name: 'release', usage: 'release doctor [--full]', summary: 'Maintainers: check release readiness', load: () => import('../commands/release.mjs'), fn: 'run' }
27
+ ];
28
+
29
+ export async function run(argv = process.argv.slice(2)) {
30
+ const [first, ...rest] = argv;
31
+
32
+ if (first === '--version' || first === '-v') {
33
+ console.log(readPackageVersion());
34
+ return 0;
35
+ }
36
+ if (first === '--help' || first === '-h' || first === 'help') {
37
+ console.log(formatHelp());
38
+ return 0;
39
+ }
40
+
41
+ if (first !== 'mcp') {
42
+ reportMigration(migrateLegacyHome());
43
+ }
44
+
45
+ if (!first || first.startsWith('-')) {
46
+ const tui = await import('../commands/tui.mjs');
47
+ return tui.run(argv);
48
+ }
49
+
50
+ const command = COMMANDS.find((item) => item.name === first);
51
+ if (!command) {
52
+ console.error(`Unknown command: ${first}\n`);
53
+ console.error(formatHelp());
54
+ return 1;
55
+ }
56
+
57
+ if (command.name === 'mcp') {
58
+ migrateLegacyHome();
59
+ }
60
+ const module = await command.load();
61
+ const result = await module[command.fn](rest);
62
+ return typeof result === 'number' ? result : undefined;
63
+ }
64
+
65
+ export function formatHelp() {
66
+ const width = Math.max(...COMMANDS.map((command) => command.name.length));
67
+ return `Usage:
68
+ logwork Open the terminal UI
69
+ logwork <command> Run one command (add --help for its options)
70
+
71
+ Commands:
72
+ ${COMMANDS.map((command) => ` ${command.name.padEnd(width)} ${command.summary}`).join('\n')}
73
+
74
+ Examples:
75
+ logwork setup
76
+ logwork login
77
+ logwork query this-week
78
+ logwork quick -m "Fix login bug (SCB-12)"
79
+ logwork edit 304032 --task "Bug Fix" --desc "Fix date picker timezone (SAP-42)"
80
+
81
+ Options:
82
+ -h, --help Show help
83
+ -v, --version Show version`;
84
+ }
85
+
86
+ function reportMigration(result) {
87
+ if (result?.migrated) {
88
+ console.error(`Moved local settings from ${result.from} to ${result.to}.`);
89
+ }
90
+ }
91
+
92
+ if (isMainModule(import.meta.url)) {
93
+ run().then((code) => {
94
+ if (typeof code === 'number') {
95
+ process.exitCode = code;
96
+ }
97
+ }).catch((error) => {
98
+ console.error(error.message);
99
+ process.exitCode = 1;
100
+ });
101
+ }