@ai-digital-factory/lmt-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,151 @@
1
- # Temporary Holding Version
1
+ # Live Market Terminal 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
+ The CLI talks to the selected Origin through public Gate. It supports only `local` and `dev`; commands that authenticate or inspect an Operator Session require an explicit target. A named CLI Client Profile keeps Gate's Client Identity and Operator Session cookies across invocations in `~/.lmt/secrets.pem` (JSON version `2` with one `sessions` entry per environment/origin/operator). Legacy version `1` files are migrated automatically on the next read or write.
4
+
5
+ Interactive mode restores a saved Operator Session on startup when Gate still accepts it, similar to reopening the website with existing cookies. The CLI reports Operator Activity to Gate on resume, after login, and while the action menu is open so idle renewal matches the web client. When Gate rejects the session, the CLI returns to Operator Login and shows the reason above the prompt.
6
+
7
+ ## Install from npm
8
+
9
+ Requires Node.js 22 or later. Install without a source checkout:
10
+
11
+ ```sh
12
+ npm install --global @ai-digital-factory/lmt-cli
13
+ lmt --help
14
+ lmt interactive --env dev --profile my-dev-session
15
+ lmt status --env dev --profile my-dev-session
16
+ ```
17
+
18
+ `live-market-terminal` is an alias of `lmt`. Both preserve the existing interactive
19
+ and headless command syntax. Provision the protected SMS read credential with
20
+ `lmt interactive credential provision --env dev`, or use
21
+ `lmt credential provision --env dev --profile default --credential-stdin` with
22
+ protected stdin as described below. Installation never provisions credentials.
23
+ The package includes canonical non-secret local/dev Origins, Gate scopes, and
24
+ SMS endpoint; it needs no repository configuration in the current directory.
25
+ Local use still requires a running local stack. Production targets remain unavailable.
26
+
27
+ ## Maintain the npm package
28
+
29
+ The **Release LMT CLI** GitHub Action is dispatched manually on `main`. It builds
30
+ current `main`, tests the CLI, builds a standalone package with bundled private
31
+ contracts, selects the next npm patch, and tests a clean installation of the exact
32
+ tarball it publishes publicly under `latest`. Node 22 and pnpm 10.33.3 match CI.
33
+
34
+ Only `SMS_CREDENTIAL` is configured as a GitHub Actions secret for this workflow.
35
+ It must be able to read `NPM_TOKEN` from SMS scope `infra`, at Vault
36
+ `secret/data/infra/NPM_TOKEN` with field `value`. The endpoint and scope are
37
+ non-secret repository configuration. The existing npm token needs publishing
38
+ permission for `@ai-digital-factory/lmt-cli`; it is masked and passed only to the
39
+ publishing step. No credential values are included in the package.
40
+
41
+ First publication uses `0.1.0`; later runs increment the highest published stable
42
+ version's patch. Registry/authentication failures stop the release. Versions change
43
+ only in the temporary publishing artifact, with no bump commit, git tag, GitHub
44
+ Release, Origin Version, or deployment. A retry after successful npm publication
45
+ selects another patch, since published npm versions are immutable.
46
+
47
+ To reproduce the packaging checks from the repository root:
48
+
49
+ ```sh
50
+ (cd live-market-terminal && pnpm --filter @ai-digital-factory/lmt-cli package:build)
51
+ tarball=$(bash .github/scripts/pack-lmt-cli.sh /tmp/lmt-cli-package)
52
+ node .github/scripts/test-lmt-cli-package.mjs "$tarball"
53
+ ```
54
+
55
+ ## Interactive use
56
+
57
+ Run `pnpm cli --help` or `node apps/cli/dist/index.js --help` for usage, exit codes, and monorepo entrypoints. The CLI sets `NODE_USE_ENV_PROXY=0` on startup so local Gate calls are not sent through `HTTP(S)_PROXY`. Both targets use the canonical public Origin from `lmt.config.json`. For local, keep Web, Gate, and Broker running with `pnpm dev:local`; Web proxies `/api` to Gate. The CLI never switches to another Origin or Gate port.
58
+
59
+ Run the terminal UI with `--env local|dev` (interactive defaults to **local**). The profile defaults to `default`.
60
+
61
+ ```sh
62
+ pnpm cli
63
+ pnpm cli --profile default
64
+ pnpm cli --env dev --profile my-dev-session
65
+ ```
66
+
67
+ Provision the SMS read credential from a masked prompt. The credential is shared across profiles. If `~/.lmt` or `secrets.pem` already exist with relaxed permissions (for example after editing in an IDE), the CLI repairs owner-only modes before reading or writing.
68
+
69
+ ```sh
70
+ pnpm --filter @ai-digital-factory/lmt-cli interactive credential provision --env dev --profile default
71
+ ```
72
+
73
+ The `interactive` script rebuilds the CLI before each run. Prefer `pnpm cli --env local` for the login TUI after credentials are stored.
74
+
75
+ ## Headless use
76
+
77
+ The workspace configures pnpm’s silent reporter so `pnpm cli:headless` does not echo its script or OTP arguments. `pnpm -s cli:headless` also works, as does `node apps/cli/dist/index.js` after building. The headless commands write one versioned JSON object per line to stdout. Diagnostics go to stderr. Exit codes are `0` for success or validation pass, `1` for an action failure, `2` for invalid invocation or target, `3` when Gate requires Operator Login, and `4` when validation is blocked or Zerodha login awaits a human OTP.
78
+
79
+ Provision an SMS read credential through protected stdin. The terminal prompt below does not echo input; SMS credentials are supplied through stdin. Zerodha OTPs use the explicit `--otp` argument described below.
80
+
81
+ ```sh
82
+ read -s -r SMS_CREDENTIAL
83
+ printf '%s\n' "$SMS_CREDENTIAL" | pnpm -s cli:headless credential provision --env dev --profile my-dev-session --credential-stdin
84
+ unset SMS_CREDENTIAL
85
+ ```
86
+
87
+ Use the selected Gate SMS scope to read the `live-market-terminal-operator-directory` and log in through Gate. `status` confirms the saved Operator Session with Gate and verifies its Operator through the Broker-backed operators route. An unavailable Broker is an action failure, while interactive resume can still check Gate session presence without Broker.
88
+
89
+ ```sh
90
+ pnpm -s cli:headless login --env dev --profile my-dev-session
91
+ pnpm -s cli:headless logout --env dev --profile my-dev-session
92
+ pnpm -s cli:headless status --env dev --profile my-dev-session
93
+ pnpm -s cli:headless validate operator-session --env dev --profile my-dev-session
94
+ ```
95
+
96
+ An expired or rejected session is cleared for that profile and target; `status` exits with code `3`. Run `login` explicitly to create a new session. Profiles are isolated by selected environment, canonical Origin, and configured Operator. Validation uses a unique temporary profile, logs out its sessions through Gate, and removes only its temporary profile records.
97
+
98
+ The default action deadline is 30 seconds and validation defaults to 2 minutes. Override it with a finite duration up to 10 minutes, such as `--timeout 45s` or `--timeout 30000ms`.
99
+
100
+ ```sh
101
+ pnpm -s cli:headless status --env local --profile default --timeout 45s
102
+ ```
103
+
104
+ ## Local and dev smoke checks
105
+
106
+ Start the local Gate and Broker stack with `pnpm dev:local`, using the service configuration in `.env.local`, or use the already deployed dev Origin. The CLI’s protected SMS read credential is separate from the service credential used by Gate and Broker. Provision the user-provided SMS read credential once through the masked interactive prompt or protected stdin above. Then exercise the same profile in separate processes:
107
+
108
+ ```sh
109
+ pnpm -s cli:headless login --env local --profile smoke-local
110
+ pnpm -s cli:headless status --env local --profile smoke-local
111
+ pnpm -s cli:headless validate operator-session --env local --profile smoke-local
112
+
113
+ pnpm -s cli:headless login --env dev --profile smoke-dev
114
+ pnpm -s cli:headless status --env dev --profile smoke-dev
115
+ pnpm -s cli:headless validate operator-session --env dev --profile smoke-dev
116
+ ```
117
+
118
+ For the interactive smoke check, run `pnpm cli --env local --profile smoke-interactive` (or select `dev`), enter the Operator Login credentials when prompted, then use menu item `3 Validate Operator Session`. The validation output must show a pass and successful cleanup. Try `pnpm -s cli:headless status --env prod --profile smoke-prod` to confirm unsupported production targeting returns exit code `2` without network access.
119
+
120
+ Interactive Operator Login returns to the username prompt after rejected credentials, with both previous entries available for editing. At the password prompt, press Escape to return to the username; press Ctrl+U to clear either field. The password stays masked and is retained only in memory for retries, then cleared after successful login or the login deadline.
121
+
122
+ Keep passwords, cookies, and SMS credentials out of command arguments. Supply the transient Zerodha OTP with `--otp`. The CLI stores the protected SMS read credential, Gate-issued cookies, and non-secret pending Zerodha attempt IDs; Operator Login passwords are read transiently from the selected Gate SMS scope and sent only to Gate.
123
+
124
+ ## Headless Login with Zerodha
125
+
126
+ First establish the Operator Session with `login`. Zerodha credentials stay on Broker. Supply the current six-digit OTP directly with `--otp`:
127
+
128
+ ```sh
129
+ pnpm -s cli:headless --env local --profile default zerodha login --otp CURRENT_OTP
130
+ ```
131
+
132
+ Replace `CURRENT_OTP` with the current six-digit code. Agents can use the OTP provided in a user message as the flag value. The CLI starts or resumes the profile's attempt automatically and verifies the resulting Zerodha Session through Gate. It excludes the OTP from its JSON results and diagnostics and never stores it. `--otp-stdin` has been removed.
133
+
134
+ To start the challenge before obtaining the OTP, run the same command without `--otp`:
135
+
136
+ ```sh
137
+ pnpm -s cli:headless --env local --profile default zerodha login
138
+ ```
139
+
140
+ An OTP challenge returns `outcome: "blocked"`, `reason: "awaiting_otp"`, and exit code `4`. Once you obtain the OTP, repeat `zerodha login --otp CURRENT_OTP`. The CLI remembers the attempt for that profile, target, and Operator Session, so no copying of attempt IDs is required. One-command login inspects remembered state before submitting: expired or failed attempts start a fresh challenge, and a succeeded attempt is reused only after the hard session check.
141
+
142
+ ```sh
143
+ pnpm -s cli:headless zerodha observe --env local --profile default
144
+ pnpm -s cli:headless zerodha status --env local --profile default
145
+ ```
146
+
147
+ `zerodha otp --otp CURRENT_OTP` also submits to the remembered attempt. `--attempt ID` remains an optional override for advanced observe/OTP calls. Successful login clears the remembered attempt, as do Operator logout, session rejection, and replacement of the Operator Session. Invalid OTPs retain Broker's rejection message and retry count. Every command remains noninteractive and honors `--timeout`.
148
+
149
+ `logout` revokes the Operator Session through Gate and then removes that target's saved cookies. If Gate cannot confirm logout, the command fails and retains the cookies for retry. Other profiles and the shared SMS credential remain intact. Broker-owned SMS access tokens are retained according to the product's logout contract.
150
+
151
+ Zerodha failures identify the browser phase or Broker session setup without exposing upstream credentials or tokens. A Broker setup failure after authentication is still a failed login; it cannot be reported as a verified Zerodha Session.