@formlm/cli 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/LICENSE +21 -0
- package/README.md +236 -0
- package/bin/formlm-cli.js +14 -0
- package/dist/commands/app.d.ts +3 -0
- package/dist/commands/app.d.ts.map +1 -0
- package/dist/commands/app.js +58 -0
- package/dist/commands/app.js.map +1 -0
- package/dist/commands/auth.d.ts +3 -0
- package/dist/commands/auth.d.ts.map +1 -0
- package/dist/commands/auth.js +75 -0
- package/dist/commands/auth.js.map +1 -0
- package/dist/commands/field.d.ts +3 -0
- package/dist/commands/field.d.ts.map +1 -0
- package/dist/commands/field.js +236 -0
- package/dist/commands/field.js.map +1 -0
- package/dist/commands/profile.d.ts +3 -0
- package/dist/commands/profile.d.ts.map +1 -0
- package/dist/commands/profile.js +58 -0
- package/dist/commands/profile.js.map +1 -0
- package/dist/commands/share.d.ts +3 -0
- package/dist/commands/share.d.ts.map +1 -0
- package/dist/commands/share.js +42 -0
- package/dist/commands/share.js.map +1 -0
- package/dist/config.d.ts +20 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +85 -0
- package/dist/config.js.map +1 -0
- package/dist/exec.d.ts +19 -0
- package/dist/exec.d.ts.map +1 -0
- package/dist/exec.js +130 -0
- package/dist/exec.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +36 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp.d.ts +2 -0
- package/dist/mcp.d.ts.map +1 -0
- package/dist/mcp.js +327 -0
- package/dist/mcp.js.map +1 -0
- package/dist/output.d.ts +6 -0
- package/dist/output.d.ts.map +1 -0
- package/dist/output.js +24 -0
- package/dist/output.js.map +1 -0
- package/package.json +41 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024-present FormLM (https://formlm.me)
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
# formlm-cli
|
|
2
|
+
|
|
3
|
+
> The official CLI & MCP Server for [FormLM](https://formlm.me) — let AI Agents build and manage your forms directly.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/@formlm/cli)
|
|
6
|
+
[](LICENSE)
|
|
7
|
+
[](https://nodejs.org)
|
|
8
|
+
|
|
9
|
+
**Keywords**: FormLM CLI, MCP Server, AI Agent form builder, form automation, assessment platform CLI, Claude MCP, Cursor MCP, AI-powered forms, formlm-cli, npm CLI tool
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## What is FormLM?
|
|
14
|
+
|
|
15
|
+
**[FormLM](https://formlm.me)** is an AI-powered form & assessment platform. It lets you build smart forms, scoring quizzes, and professional evaluation reports — all with natural language instructions.
|
|
16
|
+
|
|
17
|
+
With `formlm-cli`, you can control FormLM directly from your terminal or plug it into any AI Agent (Claude, Cursor, GPT, etc.) as an **MCP Server** — no UI needed.
|
|
18
|
+
|
|
19
|
+
> Visit the official website: **[https://formlm.me](https://formlm.me)**
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Features
|
|
24
|
+
|
|
25
|
+
- **Dual-mode**: run as a terminal CLI *or* as an MCP Server for AI Agents
|
|
26
|
+
- **20 built-in tools** covering full Auth / App / Field / Share lifecycle
|
|
27
|
+
- **Multi-profile support** — manage multiple accounts or environments
|
|
28
|
+
- **Token auth** — simple and secure, stored locally with 600 permissions
|
|
29
|
+
- **MCP-ready** — plug into Claude Desktop, Cursor, or any MCP-compatible client out of the box
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Installation
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
npm install -g @formlm/cli
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Requires Node.js ≥ 18.
|
|
40
|
+
|
|
41
|
+
For a detailed step-by-step guide (including MCP setup for Claude / Cursor), see **[INSTALL.md](INSTALL.md)**.
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## Quick Start
|
|
46
|
+
|
|
47
|
+
### 1. Login
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
formlm-cli auth login
|
|
51
|
+
# or use a token directly
|
|
52
|
+
formlm-cli auth login --token <your-token>
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
> You can also get your token from [formlm.me](https://formlm.me): open DevTools → Application → Cookies → copy the `Authorization` value.
|
|
56
|
+
|
|
57
|
+
### 2. Use the CLI
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
# List all apps
|
|
61
|
+
formlm-cli app list
|
|
62
|
+
|
|
63
|
+
# Create a new app
|
|
64
|
+
formlm-cli app create --name "Customer Survey" --description "2024 annual survey"
|
|
65
|
+
|
|
66
|
+
# Add a field
|
|
67
|
+
formlm-cli field add --app <appId> --id q1 --name "Your Name" --type input --required
|
|
68
|
+
|
|
69
|
+
# Add a radio field with scores
|
|
70
|
+
formlm-cli field add --app <appId> --id s1 --type radio --options "Satisfied:3,Neutral:2,Unsatisfied:1"
|
|
71
|
+
|
|
72
|
+
# Publish the form
|
|
73
|
+
formlm-cli share publish --app <appId>
|
|
74
|
+
|
|
75
|
+
# Get the shareable URL
|
|
76
|
+
formlm-cli share url --app <appId>
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### 3. Use as MCP Server
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
formlm-cli mcp
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
This starts the MCP Server (stdio transport), ready for AI Agents to connect.
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## Command Reference
|
|
90
|
+
|
|
91
|
+
### Auth
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
formlm-cli auth login # Interactive login
|
|
95
|
+
formlm-cli auth login --token <tok> # Login with token
|
|
96
|
+
formlm-cli auth status # Check current login state
|
|
97
|
+
formlm-cli auth logout # Clear local token
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Profile (multi-account)
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
formlm-cli profile add --name work --url https://formlm.me --token <tok>
|
|
104
|
+
formlm-cli profile list
|
|
105
|
+
formlm-cli profile use work # Switch default profile
|
|
106
|
+
formlm-cli --profile work app list # Use a profile for one command
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### App
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
formlm-cli app list
|
|
113
|
+
formlm-cli app create --name "My Form" --description "..."
|
|
114
|
+
formlm-cli app get --app <appId>
|
|
115
|
+
formlm-cli app update --app <appId> --name "New Name" --theme blue
|
|
116
|
+
formlm-cli app delete --app <appId>
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### Field
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
formlm-cli field schema # All supported field types
|
|
123
|
+
formlm-cli field config --type radio # Configurable props for a type
|
|
124
|
+
formlm-cli field list --app <appId>
|
|
125
|
+
formlm-cli field find --app <appId> --id q1 # Get a single field
|
|
126
|
+
formlm-cli field find --app <appId> --filter "name" # Search fields by keyword
|
|
127
|
+
formlm-cli field add --app <appId> --id q1 --name "Name" --type input --required
|
|
128
|
+
formlm-cli field add --app <appId> --id n1 --type scale --min 1 --max 10
|
|
129
|
+
formlm-cli field update --app <appId> --id q1 --title "Your Full Name"
|
|
130
|
+
formlm-cli field remove --app <appId> --id q1
|
|
131
|
+
formlm-cli field set-property --app <appId> --id q1 --property options.0.score --value 5
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### Share
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
formlm-cli share publish --app <appId> # Publish (permanent, single submission)
|
|
138
|
+
formlm-cli share unpublish --app <appId> # Unpublish
|
|
139
|
+
formlm-cli share query --app <appId> # Check publish status
|
|
140
|
+
formlm-cli share url --app <appId> # Get the shareable URL
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## MCP Integration
|
|
146
|
+
|
|
147
|
+
### Claude Desktop
|
|
148
|
+
|
|
149
|
+
Add to your `claude_desktop_config.json`:
|
|
150
|
+
|
|
151
|
+
```json
|
|
152
|
+
{
|
|
153
|
+
"mcpServers": {
|
|
154
|
+
"formlm": {
|
|
155
|
+
"command": "formlm-cli",
|
|
156
|
+
"args": ["mcp"]
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
> **No token? No problem.** If you omit `FORMLM_TOKEN`, the AI will prompt you to authenticate via the `auth_login` tool — just provide your token or email + password directly in the chat.
|
|
163
|
+
|
|
164
|
+
### Cursor / VS Code
|
|
165
|
+
|
|
166
|
+
Add the same block to `.cursor/mcp.json`.
|
|
167
|
+
|
|
168
|
+
### Let your AI Agent install it
|
|
169
|
+
|
|
170
|
+
Paste this into any AI chat:
|
|
171
|
+
|
|
172
|
+
```
|
|
173
|
+
Help me install FormLM CLI from https://github.com/formlm/cli,
|
|
174
|
+
then run: formlm-cli auth login
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
## Available MCP Tools (20)
|
|
180
|
+
|
|
181
|
+
| Category | Tool | Description |
|
|
182
|
+
|---|---|---|
|
|
183
|
+
| Auth | `auth_login` | Login with token or email + password |
|
|
184
|
+
| Auth | `auth_status` | Check current login status |
|
|
185
|
+
| App | `app_list` | List all apps |
|
|
186
|
+
| App | `app_create` | Create a new app |
|
|
187
|
+
| App | `app_get` | Get app details |
|
|
188
|
+
| App | `app_update` | Update app name / description / theme |
|
|
189
|
+
| App | `app_delete` | Delete an app |
|
|
190
|
+
| Field | `field_schema` | List all supported field types |
|
|
191
|
+
| Field | `field_config` | Get configurable properties for a field type |
|
|
192
|
+
| Field | `field_list` | List all fields in an app |
|
|
193
|
+
| Field | `field_find` | Get a single field by ID or keyword |
|
|
194
|
+
| Field | `field_add` | Add a new field |
|
|
195
|
+
| Field | `field_update` | Update a field |
|
|
196
|
+
| Field | `field_remove` | Remove a field |
|
|
197
|
+
| Field | `field_move` | Move a field to a specific position |
|
|
198
|
+
| Field | `field_set_property` | Fine-grained field property update |
|
|
199
|
+
| Share | `share_publish` | Publish the form |
|
|
200
|
+
| Share | `share_unpublish` | Unpublish the form |
|
|
201
|
+
| Share | `share_query` | Query publish status |
|
|
202
|
+
| Share | `share_url` | Get the form fill-in URL |
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
## Environment Variables
|
|
207
|
+
|
|
208
|
+
| Variable | Description |
|
|
209
|
+
|---|---|
|
|
210
|
+
| `FORMLM_BASE_URL` | FormLM server URL (default: `https://formlm.me`) |
|
|
211
|
+
| `FORMLM_TOKEN` | Your auth token (alternative to `auth login`) |
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
## Links
|
|
216
|
+
|
|
217
|
+
- **Website**: [https://formlm.me](https://formlm.me)
|
|
218
|
+
- **Platform**: Sign up and start building at [formlm.me](https://formlm.me)
|
|
219
|
+
- **GitHub**: [https://github.com/formlm/cli](https://github.com/formlm/cli)
|
|
220
|
+
- **npm**: [https://www.npmjs.com/package/@formlm/cli](https://www.npmjs.com/package/@formlm/cli)
|
|
221
|
+
|
|
222
|
+
---
|
|
223
|
+
|
|
224
|
+
## Contact
|
|
225
|
+
|
|
226
|
+
Have questions, feedback, or need help getting started?
|
|
227
|
+
|
|
228
|
+
📧 **[formlm.me@gmail.com](mailto:formlm.me@gmail.com)**
|
|
229
|
+
|
|
230
|
+
Feel free to reach out — we're happy to help.
|
|
231
|
+
|
|
232
|
+
---
|
|
233
|
+
|
|
234
|
+
## License
|
|
235
|
+
|
|
236
|
+
MIT © [FormLM](https://formlm.me)
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
import { dirname, join } from 'node:path';
|
|
5
|
+
|
|
6
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
7
|
+
const args = process.argv.slice(2);
|
|
8
|
+
|
|
9
|
+
if (args[0] === 'mcp') {
|
|
10
|
+
const { startMcpServer } = await import(join(__dirname, '..', 'dist', 'mcp.js'));
|
|
11
|
+
await startMcpServer();
|
|
12
|
+
} else {
|
|
13
|
+
await import(join(__dirname, '..', 'dist', 'index.js'));
|
|
14
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../../src/commands/app.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAwDxD"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { execCommand } from '../exec.js';
|
|
2
|
+
import { output } from '../output.js';
|
|
3
|
+
export function registerAppCommand(parent) {
|
|
4
|
+
const app = parent.command('app').description('App management');
|
|
5
|
+
app
|
|
6
|
+
.command('list')
|
|
7
|
+
.description('List all apps')
|
|
8
|
+
.action(async () => {
|
|
9
|
+
const result = await execCommand('assess app list --json');
|
|
10
|
+
output(result);
|
|
11
|
+
});
|
|
12
|
+
app
|
|
13
|
+
.command('create')
|
|
14
|
+
.description('Create a new app')
|
|
15
|
+
.requiredOption('--name <name>', 'App name')
|
|
16
|
+
.option('--description <desc>', 'App description')
|
|
17
|
+
.action(async (opts) => {
|
|
18
|
+
const cmd = `assess app create --name "${opts.name}"${opts.description ? ` --description "${opts.description}"` : ''} --json`;
|
|
19
|
+
const result = await execCommand(cmd);
|
|
20
|
+
output(result);
|
|
21
|
+
});
|
|
22
|
+
app
|
|
23
|
+
.command('get')
|
|
24
|
+
.description('Get app details')
|
|
25
|
+
.requiredOption('--app <appId>', 'App ID')
|
|
26
|
+
.action(async (opts) => {
|
|
27
|
+
const result = await execCommand(`assess app use --app ${opts.app} --json`);
|
|
28
|
+
output(result);
|
|
29
|
+
});
|
|
30
|
+
app
|
|
31
|
+
.command('update')
|
|
32
|
+
.description('Update an app')
|
|
33
|
+
.requiredOption('--app <appId>', 'App ID')
|
|
34
|
+
.option('--name <name>', 'New app name')
|
|
35
|
+
.option('--description <desc>', 'New description')
|
|
36
|
+
.option('--theme <theme>', 'App theme')
|
|
37
|
+
.action(async (opts) => {
|
|
38
|
+
let cmd = `assess app update --app ${opts.app}`;
|
|
39
|
+
if (opts.name)
|
|
40
|
+
cmd += ` --name "${opts.name}"`;
|
|
41
|
+
if (opts.description)
|
|
42
|
+
cmd += ` --description "${opts.description}"`;
|
|
43
|
+
if (opts.theme)
|
|
44
|
+
cmd += ` --theme ${opts.theme}`;
|
|
45
|
+
cmd += ' --json';
|
|
46
|
+
const result = await execCommand(cmd);
|
|
47
|
+
output(result);
|
|
48
|
+
});
|
|
49
|
+
app
|
|
50
|
+
.command('delete')
|
|
51
|
+
.description('Delete an app')
|
|
52
|
+
.requiredOption('--app <appId>', 'App ID')
|
|
53
|
+
.action(async (opts) => {
|
|
54
|
+
const result = await execCommand(`assess app remove --app ${opts.app} --json`);
|
|
55
|
+
output(result);
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=app.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app.js","sourceRoot":"","sources":["../../src/commands/app.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAEtC,MAAM,UAAU,kBAAkB,CAAC,MAAe;IAChD,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC,gBAAgB,CAAC,CAAC;IAEhE,GAAG;SACA,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,eAAe,CAAC;SAC5B,MAAM,CAAC,KAAK,IAAI,EAAE;QACjB,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,wBAAwB,CAAC,CAAC;QAC3D,MAAM,CAAC,MAAM,CAAC,CAAC;IACjB,CAAC,CAAC,CAAC;IAEL,GAAG;SACA,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,kBAAkB,CAAC;SAC/B,cAAc,CAAC,eAAe,EAAE,UAAU,CAAC;SAC3C,MAAM,CAAC,sBAAsB,EAAE,iBAAiB,CAAC;SACjD,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;QACrB,MAAM,GAAG,GAAG,6BAA6B,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,mBAAmB,IAAI,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC;QAC9H,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,GAAG,CAAC,CAAC;QACtC,MAAM,CAAC,MAAM,CAAC,CAAC;IACjB,CAAC,CAAC,CAAC;IAEL,GAAG;SACA,OAAO,CAAC,KAAK,CAAC;SACd,WAAW,CAAC,iBAAiB,CAAC;SAC9B,cAAc,CAAC,eAAe,EAAE,QAAQ,CAAC;SACzC,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;QACrB,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,wBAAwB,IAAI,CAAC,GAAG,SAAS,CAAC,CAAC;QAC5E,MAAM,CAAC,MAAM,CAAC,CAAC;IACjB,CAAC,CAAC,CAAC;IAEL,GAAG;SACA,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,eAAe,CAAC;SAC5B,cAAc,CAAC,eAAe,EAAE,QAAQ,CAAC;SACzC,MAAM,CAAC,eAAe,EAAE,cAAc,CAAC;SACvC,MAAM,CAAC,sBAAsB,EAAE,iBAAiB,CAAC;SACjD,MAAM,CAAC,iBAAiB,EAAE,WAAW,CAAC;SACtC,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;QACrB,IAAI,GAAG,GAAG,2BAA2B,IAAI,CAAC,GAAG,EAAE,CAAC;QAChD,IAAI,IAAI,CAAC,IAAI;YAAE,GAAG,IAAI,YAAY,IAAI,CAAC,IAAI,GAAG,CAAC;QAC/C,IAAI,IAAI,CAAC,WAAW;YAAE,GAAG,IAAI,mBAAmB,IAAI,CAAC,WAAW,GAAG,CAAC;QACpE,IAAI,IAAI,CAAC,KAAK;YAAE,GAAG,IAAI,YAAY,IAAI,CAAC,KAAK,EAAE,CAAC;QAChD,GAAG,IAAI,SAAS,CAAC;QACjB,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,GAAG,CAAC,CAAC;QACtC,MAAM,CAAC,MAAM,CAAC,CAAC;IACjB,CAAC,CAAC,CAAC;IAEL,GAAG;SACA,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,eAAe,CAAC;SAC5B,cAAc,CAAC,eAAe,EAAE,QAAQ,CAAC;SACzC,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;QACrB,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,2BAA2B,IAAI,CAAC,GAAG,SAAS,CAAC,CAAC;QAC/E,MAAM,CAAC,MAAM,CAAC,CAAC;IACjB,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAyEzD"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { authLogin, authMe } from '../exec.js';
|
|
2
|
+
import { addProfile, removeProfile, getActiveProfile } from '../config.js';
|
|
3
|
+
import * as readline from 'node:readline';
|
|
4
|
+
export function registerAuthCommand(parent) {
|
|
5
|
+
const auth = parent.command('auth').description('Authentication management');
|
|
6
|
+
auth
|
|
7
|
+
.command('login')
|
|
8
|
+
.description('Log in to FormLM')
|
|
9
|
+
.option('--token <token>', 'Log in directly with a token')
|
|
10
|
+
.option('--url <url>', 'Server URL', 'https://formlm.me')
|
|
11
|
+
.action(async (opts) => {
|
|
12
|
+
if (opts.token) {
|
|
13
|
+
// Use token directly
|
|
14
|
+
addProfile({ name: 'default', url: opts.url, token: opts.token, active: true });
|
|
15
|
+
// Verify token
|
|
16
|
+
const result = await authMe();
|
|
17
|
+
if (result.code === 0) {
|
|
18
|
+
console.log('✅ Login successful!');
|
|
19
|
+
console.log(` User: ${JSON.stringify(result.data)}`);
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
console.log(`⚠️ Token saved but verification failed: ${result.message}`);
|
|
23
|
+
}
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
// Interactive input
|
|
27
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
28
|
+
const ask = (q) => new Promise(res => rl.question(q, res));
|
|
29
|
+
const email = await ask('Email: ');
|
|
30
|
+
const password = await ask('Password: ');
|
|
31
|
+
rl.close();
|
|
32
|
+
const result = await authLogin(email, password);
|
|
33
|
+
if (result.code === 0 && result.data) {
|
|
34
|
+
const token = typeof result.data === 'string' ? result.data : result.data.token || '';
|
|
35
|
+
addProfile({ name: 'default', url: opts.url, token, active: true });
|
|
36
|
+
console.log('✅ Login successful!');
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
console.log(`❌ Login failed: ${result.message}`);
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
auth
|
|
43
|
+
.command('status')
|
|
44
|
+
.description('Show current login status')
|
|
45
|
+
.action(async () => {
|
|
46
|
+
const profile = getActiveProfile();
|
|
47
|
+
if (!profile) {
|
|
48
|
+
console.log('❌ Not logged in. Run: formlm-cli auth login');
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
console.log(`Profile: ${profile.name}`);
|
|
52
|
+
console.log(`Server: ${profile.url}`);
|
|
53
|
+
const result = await authMe();
|
|
54
|
+
if (result.code === 0) {
|
|
55
|
+
console.log(`Status: ✅ Logged in`);
|
|
56
|
+
console.log(`User: ${JSON.stringify(result.data)}`);
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
console.log(`Status: ❌ Token invalid (${result.message})`);
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
auth
|
|
63
|
+
.command('logout')
|
|
64
|
+
.description('Log out and clear local token')
|
|
65
|
+
.action(() => {
|
|
66
|
+
const profile = getActiveProfile();
|
|
67
|
+
if (!profile) {
|
|
68
|
+
console.log('Already logged out.');
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
removeProfile(profile.name);
|
|
72
|
+
console.log('✅ Logged out.');
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"field.d.ts","sourceRoot":"","sources":["../../src/commands/field.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAuM1D"}
|