@ai-digital-factory/lmt-web-cli 0.0.0-stage → 0.1.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.
package/README.md CHANGED
@@ -1,3 +1,260 @@
1
- # Temporary Holding Version
1
+ # Live Market Terminal Web 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
+ `@ai-digital-factory/lmt-web-cli` provides the separate `lmt-web` executable for
4
+ browser interaction with the configured local or dev Live Market Terminal Web URL. It
5
+ keeps browser dependencies and session lifetime out of the browser-free `lmt`
6
+ HTTP CLI.
7
+
8
+ ## Install
9
+
10
+ Requires Node.js 22 or later, Chromium, and a macOS or Linux session owner.
11
+ Install the CLI and its browser:
12
+
13
+ ```sh
14
+ npm install --global @ai-digital-factory/lmt-web-cli@latest
15
+ lmt-web install-browser
16
+ lmt-web --help
17
+ ```
18
+
19
+ `install-browser` uses the Playwright dependency installed with this CLI; a global
20
+ `playwright` executable is not required. On Linux machines missing browser system
21
+ libraries, use `lmt-web install-browser --with-deps` (the system package installer
22
+ may request elevated privileges). `--dry-run` lists the selected Chromium build
23
+ and installation path without downloading it. Setup writes one JSON result to
24
+ stdout and installer diagnostics to stderr; a failed installer returns nonzero.
25
+ If `start` reports `browser_unavailable`, rerun `lmt-web install-browser` before
26
+ starting a fresh session.
27
+
28
+ For local development, start the configured Live Market Terminal services from
29
+ `live-market-terminal/` with `pnpm dev:local`. The Web CLI never starts services.
30
+
31
+ ## Start, inspect, close
32
+
33
+ Browser command options may appear before or after the command. For example,
34
+ `lmt-web --env local --device desktop --headed start` is equivalent to
35
+ `lmt-web start --env local --device desktop --headed`.
36
+
37
+ Choose `local` or `dev` explicitly when starting a session. Mobile emulation and
38
+ headless mode are the defaults. The `iPhone 13` preset uses a 390 × 844 CSS
39
+ viewport, touch input, a device scale factor of 3, and this user agent:
40
+
41
+ ```text
42
+ Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/26.5 Mobile/15E148 Safari/604.1
43
+ ```
44
+ Use `--device desktop` for the 1440 × 900 desktop preset or `--headed` to show
45
+ the browser window. Desktop uses scale 1, no touch emulation, and the installed
46
+ Chromium runtime's desktop user agent. Results report the actual preset,
47
+ viewport, scale, touch support, and user agent. Changing device or browser
48
+ visibility requires a new session; these options are accepted only by `start`.
49
+ A visible browser requires an active desktop display. All automated browser tests
50
+ run headlessly, including mobile and desktop acceptance. `pnpm test` requires no
51
+ desktop display or Xvfb.
52
+
53
+ Quitting the browser from its Dock menu or closing its session window also ends
54
+ the browser session and its local owner. This does not log out the Operator or
55
+ stop Broker activity. A later `inspect` reports `session_not_found`.
56
+
57
+ ```sh
58
+ lmt-web start --env dev
59
+ lmt-web inspect --session SESSION_ID
60
+ lmt-web inspect --session SESSION_ID --full-page
61
+ lmt-web close --session SESSION_ID --full-page
62
+ lmt-web stop --session SESSION_ID
63
+ ```
64
+
65
+ `stop` terminates that session's browser process and local owner without inspecting
66
+ the page or taking a final screenshot. It also works after the browser window has
67
+ been closed manually. Supply the session ID returned by `start`; other sessions
68
+ remain running. Like `close`, it does not log out or stop Broker activity.
69
+
70
+ `start` opens the Home Page and returns a session ID. Every later command needs
71
+ that ID and talks to the same local browser process without reloading the page.
72
+ Concurrent commands within a session run in order. Different session IDs have
73
+ separate in-memory browser contexts and storage. A session is owned by the local
74
+ user who started it; closing it, losing its owner process, or restarting the
75
+ machine requires a new session. The Web CLI does not import `lmt` cookies or
76
+ save browser authentication. Closing a browser does not log out, revoke an
77
+ Operator Session, or stop Broker activity.
78
+
79
+ Each command writes one versioned JSON result to stdout and diagnostics to
80
+ stderr. Results contain the action outcome, current URL, visible page text and
81
+ controls, emulated device and actual viewport, and screenshot outcome. Images
82
+ are written to unique absolute paths in an owner-only temporary directory;
83
+ screenshots preserve the rendered page without added blur or masking. Field values
84
+ are omitted from JSON observations. Captures wait for document loading, visible
85
+ session-loading or busy indicators, fonts, visible images, and finite animations
86
+ to finish. Infinite animations do not block capture. `--timeout` sets one deadline for the command's browser action and
87
+ screenshot, from `1ms` through `10m`. If an operation exceeds it, the session is
88
+ closed. Action failures return nonzero; invalid commands and targets return exit code 2.
89
+ The JSON `error.code` is machine-readable:
90
+
91
+ | Code | Exit | Meaning |
92
+ | --- | ---: | --- |
93
+ | `invalid_invocation`, `invalid_target`, `invalid_session_id` | 2 | Fix the command or select a configured `local`/`dev` target. |
94
+ | `browser_unavailable` | 1 | Install Chromium with `lmt-web install-browser`, then retry. |
95
+ | `browser_start_failed` | 1 | The local browser owner exited before its session became ready. |
96
+ | `service_unavailable` | 1 | The selected Web URL could not be reached; start/check that service. |
97
+ | `session_not_found`, `session_unavailable` | 1 | The browser owner ended; start a fresh session. |
98
+ | `deadline_exceeded`, `action_failed` | 1 | The action failed or exceeded its finite deadline. |
99
+
100
+ Screenshots cover the viewport by default. `inspect --full-page` and
101
+ `close --full-page` explicitly capture the complete document, including
102
+ fields below the viewport. Password inputs retain the browser's normal rendering;
103
+ revealed values and echoed text remain visible in screenshots.
104
+ The screenshot metadata records `fullPage`; full-page mode applies only to that
105
+ command and does not change the next capture's default.
106
+
107
+ Screenshot failure is reported separately in `screenshot.outcome`; it does not
108
+ change an otherwise completed browser action's `outcome`.
109
+
110
+ Only configured `local` and `dev` Web URLs are supported. `prod`, implicit
111
+ targets, and target fallback are rejected. Configure those URLs in
112
+ `lmt.config.json` when running from a source checkout; the published package
113
+ contains the non-secret `local` and `dev` Web URL values.
114
+
115
+ ## Build and test the standalone package
116
+
117
+ From `live-market-terminal/`:
118
+
119
+ ```sh
120
+ pnpm --filter @ai-digital-factory/lmt-web-cli build
121
+ pnpm --filter @ai-digital-factory/lmt-web-cli typecheck
122
+ pnpm --filter @ai-digital-factory/lmt-web-cli test
123
+ pnpm --filter @ai-digital-factory/lmt-web-cli package:build
124
+ ```
125
+
126
+ Generic interaction uses controls returned by the latest observation:
127
+
128
+ ```sh
129
+ lmt-web inspect --session SESSION
130
+ lmt-web fill --session SESSION --ref REFERENCE --value "draft text"
131
+ lmt-web click --session SESSION --ref REFERENCE
132
+ lmt-web select --session SESSION --ref REFERENCE --value NSE
133
+ lmt-web scroll --session SESSION --y 500
134
+ lmt-web navigate --session SESSION --url /operator
135
+ ```
136
+
137
+ Every action returns an updated observation and screenshot. References expire with
138
+ the next observation and never identify replacement elements. Use the references
139
+ in each result for the next command. Missing, stale, and duplicate references fail
140
+ explicitly. Navigation accepts a path or URL within the session's configured Origin;
141
+ rendered links can follow the website's own handoff flow. Scroll offsets are pixels;
142
+ `--ref` optionally scrolls a returned control instead of the page. Generic actions
143
+ also accept `--timeout` and `--full-page`.
144
+
145
+ Credential fields are detected from their type, labels, and attributes. Use
146
+ `fill --secret` for sensitive values in other fields. Entered secrets remain in the
147
+ live session's redaction registry, including when echoed into text or revealed in
148
+ an input. JSON observations omit field values and redact secret text. Screenshots
149
+ show the rendered page without additional masking.
150
+ A click whose completion cannot be confirmed returns `outcome: "uncertain"` and a
151
+ nonzero exit status. Pending browser loading is stopped to retain evidence, but the
152
+ submitted server operation may still complete. Inspect before deciding what to do
153
+ next; the CLI never repeats the click automatically. Screenshot capture has its
154
+ own outcome even when the click is uncertain.
155
+
156
+ Guided Operator login uses its own protected SMS read credential in `~/.lmt-web/secrets.pem`.
157
+ Provision it through `lmt-web credential provision --env local --credential-stdin` using a secure input
158
+ source (one line). The HTTP CLI uses `~/.lmt/secrets.pem` independently. Neither
159
+ CLI copies or falls back to the other's credential. Provision Web separately,
160
+ even if an HTTP CLI credential already exists. Updating either credential leaves
161
+ the other CLI's credentials and saved sessions unchanged.
162
+
163
+ Use `--env dev` for Dev Deployment. Web CLI does not support profiles. The
164
+ environment validates the selected deployment; the SMS read credential is owned
165
+ by this CLI and is not stored per environment. The former `--stdin` invocation
166
+ remains available for compatibility.
167
+ The Web CLI reads the selected environment's Gate Operator Directory and fills
168
+ and submits the rendered Home Page form:
169
+
170
+ ```sh
171
+ lmt-web operator-login --session ID
172
+ lmt-web operator-logout --session ID
173
+ ```
174
+
175
+ Login credentials stay in the live owner process. HTTP CLI authentication cookies
176
+ are never imported. Operator logout activates Web controls and confirms Home;
177
+ `close` only closes the browser. Both commands return page observations and a
178
+ screenshot, including credential rejection or SMS lookup failure. A rejected
179
+ login is reported as `incorrect_credentials`; missing provisioning is
180
+ `sms_credential_missing`. Check the credential and selected Gate scope before
181
+ starting another login.
182
+
183
+ From the Zerodha Login Page, start the existing Web login flow explicitly:
184
+
185
+ ```sh
186
+ lmt-web zerodha-login --session ID
187
+ lmt-web zerodha-otp --session ID --attempt ATTEMPT_ID --stdin
188
+ lmt-web zerodha-logout --session ID
189
+ ```
190
+
191
+ `zerodha-login` returns `loginAttempt.attemptId` and `status: awaiting_otp` when
192
+ Web offers an OTP Challenge. Supply a fresh six-digit OTP on standard input to
193
+ `zerodha-otp`, using that exact attempt ID and browser session. The tool never
194
+ retrieves an OTP or starts a replacement during OTP submission. An explicit retry
195
+ is permitted after `otp_rejected` while the same attempt remains active.
196
+ `attempt_replaced` and `attempt_unavailable` require inspecting the current page;
197
+ neither starts another attempt. Success observes Market Watch.
198
+
199
+ `zerodha-logout` activates the Authenticated Operator logout control and returns
200
+ the Zerodha Login Page; `operator-logout` continues through Web to Home. These
201
+ controls preserve the product's Broker-owned shared state semantics.
202
+ An action reported as `uncertain` may have been submitted: inspect its screenshot
203
+ and current page before deciding what to do. No mutation is automatically replayed.
204
+ Revealed credential or OTP values remain visible in screenshots, as they do in Web.
205
+
206
+
207
+ ## Validate a fresh dev OTP Challenge
208
+
209
+ Controlled package tests cover accepted and rejected credentials and OTPs on mobile
210
+ and desktop. Live dev validation requires an authorized Operator and an OTP from
211
+ the current challenge. Do this explicitly; an OTP from a previous attempt cannot
212
+ validate a new session.
213
+
214
+ 1. Provision the SMS read credential through `credential provision --stdin` from a
215
+ secure input source, then run `lmt-web start --env dev`. Record `sessionId`, the
216
+ reported device, viewport, action outcome, and screenshot path.
217
+ 2. Run `lmt-web operator-login --session ID` and inspect the Zerodha Login Page
218
+ screenshot. Run `lmt-web zerodha-login --session ID` once. Record the returned
219
+ `loginAttempt.attemptId` only when its status is `awaiting_otp`.
220
+ 3. Obtain a fresh six-digit OTP for that active challenge from the authorized
221
+ person. Supply it on standard input to `lmt-web zerodha-otp --session ID
222
+ --attempt ATTEMPT_ID --stdin`. Do not put the OTP in command arguments, logs,
223
+ screenshots, or recorded acceptance notes. The command does not retrieve OTPs.
224
+ 4. Confirm success, Market Watch in the resulting observation, and a readable
225
+ viewport image. Run `lmt-web inspect --session ID --full-page` and inspect
226
+ its separate image and metadata. If the action is `uncertain`, inspect before
227
+ deciding anything further; do not automatically repeat the submission. If the
228
+ OTP is rejected, obtain another current OTP only while that attempt is active.
229
+ 5. To exercise explicit application logout, run `zerodha-logout` and then
230
+ `operator-logout` with that session ID, confirming their resulting pages. Run
231
+ `lmt-web close --session ID` to release the browser. Confirm a later `inspect`
232
+ reports the session is no longer live.
233
+ 6. Repeat with a new `start --env dev --device desktop` session and its own fresh
234
+ challenge and OTP. Add `--headed` when a visible browser is useful. Record the
235
+ validation date, device, non-secret outcomes, and local artifact paths. Keep
236
+ local evidence protected; this workflow does not upload it.
237
+
238
+ Closing the browser alone does not perform application logout. Separate browser
239
+ sessions still share the Operator's Broker-owned business state.
240
+
241
+ ## Clean-install acceptance
242
+
243
+ The manual **Release LMT Web CLI** GitHub Action publishes this package from
244
+ `main`. It selects the next npm patch version (or `0.1.0` for the first release),
245
+ verifies the packed tarball with headless browser acceptance, reads the npm token
246
+ through the existing CI SMS credential, and confirms public registry visibility.
247
+ It does not deploy the application or modify the HTTP CLI's npm release.
248
+
249
+ After `package:build`, run this from `live-market-terminal/`:
250
+
251
+ ```sh
252
+ node ../.github/scripts/test-lmt-web-cli-package.mjs apps/web-cli/dist/npm
253
+ ```
254
+
255
+ The script runs browser tests headlessly, packs and installs into a temporary
256
+ directory, executes the installed bin,
257
+ sets up its own Chromium runtime, verifies packaged runtime modules/configuration,
258
+ and reuses all browser acceptance tests. Installed commands and their live owners
259
+ run outside the checkout. Test-only fixture servers provide repeatable responses;
260
+ this check performs no npm publication or live dev login.