@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.
Files changed (44) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +236 -0
  3. package/bin/formlm-cli.js +14 -0
  4. package/dist/commands/app.d.ts +3 -0
  5. package/dist/commands/app.d.ts.map +1 -0
  6. package/dist/commands/app.js +58 -0
  7. package/dist/commands/app.js.map +1 -0
  8. package/dist/commands/auth.d.ts +3 -0
  9. package/dist/commands/auth.d.ts.map +1 -0
  10. package/dist/commands/auth.js +75 -0
  11. package/dist/commands/auth.js.map +1 -0
  12. package/dist/commands/field.d.ts +3 -0
  13. package/dist/commands/field.d.ts.map +1 -0
  14. package/dist/commands/field.js +236 -0
  15. package/dist/commands/field.js.map +1 -0
  16. package/dist/commands/profile.d.ts +3 -0
  17. package/dist/commands/profile.d.ts.map +1 -0
  18. package/dist/commands/profile.js +58 -0
  19. package/dist/commands/profile.js.map +1 -0
  20. package/dist/commands/share.d.ts +3 -0
  21. package/dist/commands/share.d.ts.map +1 -0
  22. package/dist/commands/share.js +42 -0
  23. package/dist/commands/share.js.map +1 -0
  24. package/dist/config.d.ts +20 -0
  25. package/dist/config.d.ts.map +1 -0
  26. package/dist/config.js +85 -0
  27. package/dist/config.js.map +1 -0
  28. package/dist/exec.d.ts +19 -0
  29. package/dist/exec.d.ts.map +1 -0
  30. package/dist/exec.js +130 -0
  31. package/dist/exec.js.map +1 -0
  32. package/dist/index.d.ts +2 -0
  33. package/dist/index.d.ts.map +1 -0
  34. package/dist/index.js +36 -0
  35. package/dist/index.js.map +1 -0
  36. package/dist/mcp.d.ts +2 -0
  37. package/dist/mcp.d.ts.map +1 -0
  38. package/dist/mcp.js +327 -0
  39. package/dist/mcp.js.map +1 -0
  40. package/dist/output.d.ts +6 -0
  41. package/dist/output.d.ts.map +1 -0
  42. package/dist/output.js +24 -0
  43. package/dist/output.js.map +1 -0
  44. package/package.json +41 -0
@@ -0,0 +1,236 @@
1
+ import { execCommand } from '../exec.js';
2
+ import { output } from '../output.js';
3
+ export function registerFieldCommand(parent) {
4
+ const field = parent.command('field').description('Field management');
5
+ field
6
+ .command('schema')
7
+ .description('List all supported field types')
8
+ .action(async () => {
9
+ const result = await execCommand('assess form types --verbose');
10
+ output(result);
11
+ });
12
+ field
13
+ .command('config')
14
+ .description('Get configurable properties for a field type')
15
+ .requiredOption('--type <type>', 'Field type')
16
+ .action(async (opts) => {
17
+ const result = await execCommand(`assess form config --type ${opts.type}`);
18
+ output(result);
19
+ });
20
+ field
21
+ .command('list')
22
+ .description('List all fields in an app')
23
+ .requiredOption('--app <appId>', 'App ID')
24
+ .action(async (opts) => {
25
+ const result = await execCommand(`assess form query --json --app ${opts.app}`);
26
+ output(result);
27
+ });
28
+ field
29
+ .command('find')
30
+ .description('Get a single field by ID or keyword')
31
+ .requiredOption('--app <appId>', 'App ID')
32
+ .option('--id <fieldId>', 'Field ID')
33
+ .option('--key <fieldKey>', 'Field Key')
34
+ .option('--filter <keyword>', 'Keyword filter')
35
+ .action(async (opts) => {
36
+ let cmd = `assess form find --app ${opts.app}`;
37
+ if (opts.id)
38
+ cmd += ` --id ${opts.id}`;
39
+ if (opts.key)
40
+ cmd += ` --key ${opts.key}`;
41
+ if (opts.filter)
42
+ cmd += ` --filter "${opts.filter}"`;
43
+ cmd += ' --json';
44
+ const result = await execCommand(cmd);
45
+ output(result);
46
+ });
47
+ field
48
+ .command('add')
49
+ .description('Add a new field')
50
+ .requiredOption('--app <appId>', 'App ID')
51
+ .requiredOption('--id <id>', 'Field ID')
52
+ .option('--type <type>', 'Field type', 'input')
53
+ .option('--title <title>', 'Field title / question text')
54
+ .option('--name <name>', 'Field name')
55
+ .option('--options <options>', 'Options list, comma-separated, supports label:score')
56
+ .option('--required', 'Mark as required')
57
+ .option('--score <score>', 'Question score')
58
+ .option('--min <min>', 'Min value')
59
+ .option('--max <max>', 'Max value')
60
+ .option('--placeholder <placeholder>', 'Placeholder text')
61
+ .option('--inputMask <inputMask>', 'Input mask')
62
+ .option('--content <content>', 'Field content / description')
63
+ .option('--answer <answer>', 'Correct answer')
64
+ .option('--explanation <explanation>', 'Answer explanation')
65
+ .option('--format <format>', 'Field format')
66
+ .option('--unique', 'Unique value validation')
67
+ .option('--shareable', 'Visible on share page')
68
+ .action(async (opts) => {
69
+ let cmd = `assess form add --app ${opts.app} --id ${opts.id} --type ${opts.type}`;
70
+ if (opts.title)
71
+ cmd += ` --title "${opts.title}"`;
72
+ if (opts.name)
73
+ cmd += ` --name "${opts.name}"`;
74
+ if (opts.options)
75
+ cmd += ` --options "${opts.options}"`;
76
+ if (opts.required)
77
+ cmd += ' --required';
78
+ if (opts.score !== undefined)
79
+ cmd += ` --score ${opts.score}`;
80
+ if (opts.min !== undefined)
81
+ cmd += ` --min ${opts.min}`;
82
+ if (opts.max !== undefined)
83
+ cmd += ` --max ${opts.max}`;
84
+ if (opts.placeholder)
85
+ cmd += ` --placeholder "${opts.placeholder}"`;
86
+ if (opts.inputMask)
87
+ cmd += ` --inputMask ${opts.inputMask}`;
88
+ if (opts.content)
89
+ cmd += ` --content "${opts.content}"`;
90
+ if (opts.answer)
91
+ cmd += ` --answer "${opts.answer}"`;
92
+ if (opts.explanation)
93
+ cmd += ` --explanation "${opts.explanation}"`;
94
+ if (opts.format)
95
+ cmd += ` --format ${opts.format}`;
96
+ if (opts.unique)
97
+ cmd += ' --unique';
98
+ if (opts.shareable)
99
+ cmd += ' --shareable';
100
+ cmd += ' --json';
101
+ const result = await execCommand(cmd);
102
+ output(result);
103
+ });
104
+ field
105
+ .command('update')
106
+ .description('Update a field')
107
+ .requiredOption('--app <appId>', 'App ID')
108
+ .option('--id <fieldId>', 'Field ID')
109
+ .option('--key <fieldKey>', 'Field Key')
110
+ .option('--type <type>', 'Field type')
111
+ .option('--title <title>', 'Field title / question text')
112
+ .option('--name <name>', 'Field name')
113
+ .option('--options <options>', 'Options list — replaces existing options')
114
+ .option('--required', 'Mark as required')
115
+ .option('--score <score>', 'Question score')
116
+ .option('--min <min>', 'Min value')
117
+ .option('--max <max>', 'Max value')
118
+ .option('--placeholder <placeholder>', 'Placeholder text')
119
+ .option('--inputMask <inputMask>', 'Input mask')
120
+ .option('--content <content>', 'Field content / description')
121
+ .option('--answer <answer>', 'Correct answer')
122
+ .option('--explanation <explanation>', 'Answer explanation')
123
+ .option('--format <format>', 'Field format')
124
+ .option('--unique', 'Unique value validation')
125
+ .option('--shareable', 'Visible on share page')
126
+ .action(async (opts) => {
127
+ if (!opts.id && !opts.key) {
128
+ console.error('❌ Either --id or --key is required');
129
+ process.exit(1);
130
+ }
131
+ let cmd = `assess form update --app ${opts.app}`;
132
+ if (opts.id)
133
+ cmd += ` --id ${opts.id}`;
134
+ if (opts.key)
135
+ cmd += ` --key ${opts.key}`;
136
+ if (opts.type)
137
+ cmd += ` --type ${opts.type}`;
138
+ if (opts.title)
139
+ cmd += ` --title "${opts.title}"`;
140
+ if (opts.name)
141
+ cmd += ` --name "${opts.name}"`;
142
+ if (opts.options)
143
+ cmd += ` --options "${opts.options}"`;
144
+ if (opts.required)
145
+ cmd += ' --required';
146
+ if (opts.score !== undefined)
147
+ cmd += ` --score ${opts.score}`;
148
+ if (opts.min !== undefined)
149
+ cmd += ` --min ${opts.min}`;
150
+ if (opts.max !== undefined)
151
+ cmd += ` --max ${opts.max}`;
152
+ if (opts.placeholder)
153
+ cmd += ` --placeholder "${opts.placeholder}"`;
154
+ if (opts.inputMask)
155
+ cmd += ` --inputMask ${opts.inputMask}`;
156
+ if (opts.content)
157
+ cmd += ` --content "${opts.content}"`;
158
+ if (opts.answer)
159
+ cmd += ` --answer "${opts.answer}"`;
160
+ if (opts.explanation)
161
+ cmd += ` --explanation "${opts.explanation}"`;
162
+ if (opts.format)
163
+ cmd += ` --format ${opts.format}`;
164
+ if (opts.unique)
165
+ cmd += ' --unique';
166
+ if (opts.shareable)
167
+ cmd += ' --shareable';
168
+ cmd += ' --json';
169
+ const result = await execCommand(cmd);
170
+ output(result);
171
+ });
172
+ field
173
+ .command('remove')
174
+ .description('Remove a field')
175
+ .requiredOption('--app <appId>', 'App ID')
176
+ .option('--id <fieldId>', 'Field ID')
177
+ .option('--key <fieldKey>', 'Field Key')
178
+ .action(async (opts) => {
179
+ if (!opts.id && !opts.key) {
180
+ console.error('❌ Either --id or --key is required');
181
+ process.exit(1);
182
+ }
183
+ let cmd = `assess form remove --app ${opts.app}`;
184
+ if (opts.id)
185
+ cmd += ` --id ${opts.id}`;
186
+ if (opts.key)
187
+ cmd += ` --key ${opts.key}`;
188
+ cmd += ' --json';
189
+ const result = await execCommand(cmd);
190
+ output(result);
191
+ });
192
+ field
193
+ .command('set-property')
194
+ .description('Fine-grained field property update')
195
+ .requiredOption('--app <appId>', 'App ID')
196
+ .option('--id <fieldId>', 'Field ID')
197
+ .option('--key <fieldKey>', 'Field Key')
198
+ .requiredOption('--property <property>', 'Property path (e.g. options.1.score)')
199
+ .requiredOption('--value <value>', 'Property value')
200
+ .action(async (opts) => {
201
+ if (!opts.id && !opts.key) {
202
+ console.error('❌ Either --id or --key is required');
203
+ process.exit(1);
204
+ }
205
+ let cmd = `assess form set-property --app ${opts.app}`;
206
+ if (opts.id)
207
+ cmd += ` --id ${opts.id}`;
208
+ if (opts.key)
209
+ cmd += ` --key ${opts.key}`;
210
+ cmd += ` --property ${opts.property} --value "${opts.value}"`;
211
+ const result = await execCommand(cmd);
212
+ output(result);
213
+ });
214
+ field
215
+ .command('move')
216
+ .description('Move a field to a specific position')
217
+ .requiredOption('--app <appId>', 'App ID')
218
+ .option('--id <fieldId>', 'Field ID')
219
+ .option('--key <fieldKey>', 'Field Key')
220
+ .requiredOption('--pos <pos>', 'Target position (1-based)', parseInt)
221
+ .action(async (opts) => {
222
+ if (!opts.id && !opts.key) {
223
+ console.error('❌ Either --id or --key is required');
224
+ process.exit(1);
225
+ }
226
+ let cmd = `assess form move --app ${opts.app}`;
227
+ if (opts.id)
228
+ cmd += ` --id ${opts.id}`;
229
+ if (opts.key)
230
+ cmd += ` --key ${opts.key}`;
231
+ cmd += ` --pos ${opts.pos}`;
232
+ const result = await execCommand(cmd);
233
+ output(result);
234
+ });
235
+ }
236
+ //# sourceMappingURL=field.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"field.js","sourceRoot":"","sources":["../../src/commands/field.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare function registerProfileCommand(parent: Command): void;
3
+ //# sourceMappingURL=profile.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"profile.d.ts","sourceRoot":"","sources":["../../src/commands/profile.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAyD5D"}
@@ -0,0 +1,58 @@
1
+ import { loadConfig, addProfile, setActiveProfile, removeProfile } from '../config.js';
2
+ export function registerProfileCommand(parent) {
3
+ const profile = parent.command('profile').description('Multi-account profile management');
4
+ profile
5
+ .command('add')
6
+ .description('Add a profile')
7
+ .option('--name <name>', 'Profile name', 'default')
8
+ .option('--url <url>', 'Server URL', 'https://formlm.me')
9
+ .option('--token <token>', 'Auth token')
10
+ .action((opts) => {
11
+ if (!opts.token) {
12
+ console.log('❌ --token is required. Get your token from FormLM website or run: formlm-cli auth login');
13
+ return;
14
+ }
15
+ addProfile({ name: opts.name, url: opts.url, token: opts.token });
16
+ console.log(`✅ Profile "${opts.name}" added.`);
17
+ });
18
+ profile
19
+ .command('list')
20
+ .description('List all profiles')
21
+ .action(() => {
22
+ const config = loadConfig();
23
+ if (config.profiles.length === 0) {
24
+ console.log('No profiles. Run: formlm-cli auth login');
25
+ return;
26
+ }
27
+ for (const p of config.profiles) {
28
+ const active = p.active ? ' (active)' : '';
29
+ const maskedToken = p.token ? p.token.substring(0, 8) + '...' : '(none)';
30
+ console.log(` ${p.name}${active} ${p.url} token: ${maskedToken}`);
31
+ }
32
+ });
33
+ profile
34
+ .command('use')
35
+ .argument('<name>', 'Profile name')
36
+ .description('Switch default profile')
37
+ .action((name) => {
38
+ if (setActiveProfile(name)) {
39
+ console.log(`✅ Switched to profile "${name}".`);
40
+ }
41
+ else {
42
+ console.log(`❌ Profile "${name}" not found.`);
43
+ }
44
+ });
45
+ profile
46
+ .command('remove')
47
+ .argument('<name>', 'Profile name')
48
+ .description('Remove a profile')
49
+ .action((name) => {
50
+ if (removeProfile(name)) {
51
+ console.log(`✅ Profile "${name}" removed.`);
52
+ }
53
+ else {
54
+ console.log(`❌ Profile "${name}" not found.`);
55
+ }
56
+ });
57
+ }
58
+ //# sourceMappingURL=profile.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"profile.js","sourceRoot":"","sources":["../../src/commands/profile.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare function registerShareCommand(parent: Command): void;
3
+ //# sourceMappingURL=share.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"share.d.ts","sourceRoot":"","sources":["../../src/commands/share.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CA0C1D"}
@@ -0,0 +1,42 @@
1
+ import { execCommand } from '../exec.js';
2
+ import { output } from '../output.js';
3
+ export function registerShareCommand(parent) {
4
+ const share = parent.command('share').description('Share & publish management');
5
+ share
6
+ .command('publish')
7
+ .description('Publish the app (permanent, single submission)')
8
+ .requiredOption('--app <appId>', 'App ID')
9
+ .action(async (opts) => {
10
+ const cmd = `assess share set --app ${opts.app} --form-type all --form-perm 1 --form-day 3650000 --json`;
11
+ const result = await execCommand(cmd);
12
+ output(result);
13
+ });
14
+ share
15
+ .command('unpublish')
16
+ .description('Unpublish the app')
17
+ .requiredOption('--app <appId>', 'App ID')
18
+ .action(async (opts) => {
19
+ const cmd = `assess share set --app ${opts.app} --form-type no --json`;
20
+ const result = await execCommand(cmd);
21
+ output(result);
22
+ });
23
+ share
24
+ .command('query')
25
+ .description('Query publish status')
26
+ .requiredOption('--app <appId>', 'App ID')
27
+ .action(async (opts) => {
28
+ const cmd = `assess share query --app ${opts.app} --json`;
29
+ const result = await execCommand(cmd);
30
+ output(result);
31
+ });
32
+ share
33
+ .command('url')
34
+ .description('Get the form fill-in URL')
35
+ .requiredOption('--app <appId>', 'App ID')
36
+ .action(async (opts) => {
37
+ const cmd = `assess share url --app ${opts.app}`;
38
+ const result = await execCommand(cmd);
39
+ output(result);
40
+ });
41
+ }
42
+ //# sourceMappingURL=share.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"share.js","sourceRoot":"","sources":["../../src/commands/share.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAEtC,MAAM,UAAU,oBAAoB,CAAC,MAAe;IAClD,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,WAAW,CAAC,4BAA4B,CAAC,CAAC;IAEhF,KAAK;SACF,OAAO,CAAC,SAAS,CAAC;SAClB,WAAW,CAAC,gDAAgD,CAAC;SAC7D,cAAc,CAAC,eAAe,EAAE,QAAQ,CAAC;SACzC,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;QACrB,MAAM,GAAG,GAAG,0BAA0B,IAAI,CAAC,GAAG,0DAA0D,CAAC;QACzG,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,GAAG,CAAC,CAAC;QACtC,MAAM,CAAC,MAAM,CAAC,CAAC;IACjB,CAAC,CAAC,CAAC;IAEL,KAAK;SACF,OAAO,CAAC,WAAW,CAAC;SACpB,WAAW,CAAC,mBAAmB,CAAC;SAChC,cAAc,CAAC,eAAe,EAAE,QAAQ,CAAC;SACzC,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;QACrB,MAAM,GAAG,GAAG,0BAA0B,IAAI,CAAC,GAAG,wBAAwB,CAAC;QACvE,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,GAAG,CAAC,CAAC;QACtC,MAAM,CAAC,MAAM,CAAC,CAAC;IACjB,CAAC,CAAC,CAAC;IAEL,KAAK;SACF,OAAO,CAAC,OAAO,CAAC;SAChB,WAAW,CAAC,sBAAsB,CAAC;SACnC,cAAc,CAAC,eAAe,EAAE,QAAQ,CAAC;SACzC,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;QACrB,MAAM,GAAG,GAAG,4BAA4B,IAAI,CAAC,GAAG,SAAS,CAAC;QAC1D,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,GAAG,CAAC,CAAC;QACtC,MAAM,CAAC,MAAM,CAAC,CAAC;IACjB,CAAC,CAAC,CAAC;IAEL,KAAK;SACF,OAAO,CAAC,KAAK,CAAC;SACd,WAAW,CAAC,0BAA0B,CAAC;SACvC,cAAc,CAAC,eAAe,EAAE,QAAQ,CAAC;SACzC,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;QACrB,MAAM,GAAG,GAAG,0BAA0B,IAAI,CAAC,GAAG,EAAE,CAAC;QACjD,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,GAAG,CAAC,CAAC;QACtC,MAAM,CAAC,MAAM,CAAC,CAAC;IACjB,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -0,0 +1,20 @@
1
+ export interface Profile {
2
+ name: string;
3
+ url: string;
4
+ token: string;
5
+ active?: boolean;
6
+ }
7
+ export interface Config {
8
+ profiles: Profile[];
9
+ }
10
+ export declare function loadConfig(): Config;
11
+ export declare function saveConfig(config: Config): void;
12
+ export declare function getActiveProfile(): Profile | null;
13
+ export declare function getProfile(name?: string): Profile | null;
14
+ export declare function getBaseUrl(): string;
15
+ export declare function getToken(profileName?: string): string;
16
+ export declare function setRuntimeProfile(name: string): void;
17
+ export declare function addProfile(profile: Profile): void;
18
+ export declare function setActiveProfile(name: string): boolean;
19
+ export declare function removeProfile(name: string): boolean;
20
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,MAAM;IACrB,QAAQ,EAAE,OAAO,EAAE,CAAC;CACrB;AAKD,wBAAgB,UAAU,IAAI,MAAM,CAUnC;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAK/C;AAED,wBAAgB,gBAAgB,IAAI,OAAO,GAAG,IAAI,CAGjD;AAED,wBAAgB,UAAU,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI,CAIxD;AAED,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAED,wBAAgB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,CAErD;AAID,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAEpD;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAajD;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAStD;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAYnD"}
package/dist/config.js ADDED
@@ -0,0 +1,85 @@
1
+ import * as fs from 'node:fs';
2
+ import * as path from 'node:path';
3
+ import * as os from 'node:os';
4
+ const CONFIG_DIR = path.join(os.homedir(), '.formlm');
5
+ const CONFIG_FILE = path.join(CONFIG_DIR, 'config.json');
6
+ export function loadConfig() {
7
+ if (!fs.existsSync(CONFIG_FILE)) {
8
+ return { profiles: [] };
9
+ }
10
+ try {
11
+ const raw = fs.readFileSync(CONFIG_FILE, 'utf-8');
12
+ return JSON.parse(raw);
13
+ }
14
+ catch {
15
+ return { profiles: [] };
16
+ }
17
+ }
18
+ export function saveConfig(config) {
19
+ if (!fs.existsSync(CONFIG_DIR)) {
20
+ fs.mkdirSync(CONFIG_DIR, { recursive: true });
21
+ }
22
+ fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2), { mode: 0o600 });
23
+ }
24
+ export function getActiveProfile() {
25
+ const config = loadConfig();
26
+ return config.profiles.find(p => p.active) || config.profiles[0] || null;
27
+ }
28
+ export function getProfile(name) {
29
+ if (!name)
30
+ return getActiveProfile();
31
+ const config = loadConfig();
32
+ return config.profiles.find(p => p.name === name) || null;
33
+ }
34
+ export function getBaseUrl() {
35
+ return process.env.FORMLM_BASE_URL || getProfile(runtimeProfile)?.url || getActiveProfile()?.url || 'https://formlm.me';
36
+ }
37
+ export function getToken(profileName) {
38
+ return process.env.FORMLM_TOKEN || getProfile(profileName || runtimeProfile)?.token || getActiveProfile()?.token || '';
39
+ }
40
+ // Runtime profile override (set by --profile global option)
41
+ let runtimeProfile;
42
+ export function setRuntimeProfile(name) {
43
+ runtimeProfile = name;
44
+ }
45
+ export function addProfile(profile) {
46
+ const config = loadConfig();
47
+ const existing = config.profiles.findIndex(p => p.name === profile.name);
48
+ if (existing >= 0) {
49
+ config.profiles[existing] = profile;
50
+ }
51
+ else {
52
+ config.profiles.push(profile);
53
+ }
54
+ // Auto-set first profile as active
55
+ if (config.profiles.length === 1) {
56
+ config.profiles[0].active = true;
57
+ }
58
+ saveConfig(config);
59
+ }
60
+ export function setActiveProfile(name) {
61
+ const config = loadConfig();
62
+ let found = false;
63
+ for (const p of config.profiles) {
64
+ p.active = p.name === name;
65
+ if (p.name === name)
66
+ found = true;
67
+ }
68
+ if (found)
69
+ saveConfig(config);
70
+ return found;
71
+ }
72
+ export function removeProfile(name) {
73
+ const config = loadConfig();
74
+ const before = config.profiles.length;
75
+ config.profiles = config.profiles.filter(p => p.name !== name);
76
+ if (config.profiles.length < before) {
77
+ if (config.profiles.length > 0 && !config.profiles.some(p => p.active)) {
78
+ config.profiles[0].active = true;
79
+ }
80
+ saveConfig(config);
81
+ return true;
82
+ }
83
+ return false;
84
+ }
85
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
package/dist/exec.d.ts ADDED
@@ -0,0 +1,19 @@
1
+ export interface ExecResult {
2
+ code: number;
3
+ message: string;
4
+ data: string | null;
5
+ }
6
+ /**
7
+ * POST /api/v1/mcp/exec
8
+ * Send CLI command to server for execution
9
+ */
10
+ export declare function execCommand(cmd: string, profileName?: string): Promise<ExecResult>;
11
+ /**
12
+ * POST /api/v1/mcp/auth/login
13
+ */
14
+ export declare function authLogin(email: string, password: string): Promise<ExecResult>;
15
+ /**
16
+ * GET /api/v1/mcp/auth/me
17
+ */
18
+ export declare function authMe(profileName?: string): Promise<ExecResult>;
19
+ //# sourceMappingURL=exec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exec.d.ts","sourceRoot":"","sources":["../src/exec.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CACrB;AAED;;;GAGG;AACH,wBAAsB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CA4CxF;AAED;;GAEG;AACH,wBAAsB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAsCpF;AAED;;GAEG;AACH,wBAAsB,MAAM,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAwCtE"}
package/dist/exec.js ADDED
@@ -0,0 +1,130 @@
1
+ import * as crypto from 'node:crypto';
2
+ import * as http from 'node:http';
3
+ import * as https from 'node:https';
4
+ import { getBaseUrl, getToken } from './config.js';
5
+ /**
6
+ * POST /api/v1/mcp/exec
7
+ * Send CLI command to server for execution
8
+ */
9
+ export async function execCommand(cmd, profileName) {
10
+ const baseUrl = getBaseUrl();
11
+ const token = getToken(profileName);
12
+ if (!token) {
13
+ return { code: 401, message: 'Not logged in. Run: formlm-cli auth login', data: null };
14
+ }
15
+ const url = new URL('/api/v1/mcp/exec', baseUrl);
16
+ const body = JSON.stringify({ cmd });
17
+ return new Promise((resolve) => {
18
+ const mod = url.protocol === 'https:' ? https : http;
19
+ const req = mod.request(url, {
20
+ method: 'POST',
21
+ headers: {
22
+ 'Content-Type': 'application/json',
23
+ 'Authorization': `Bearer ${token}`,
24
+ 'Content-Length': Buffer.byteLength(body),
25
+ },
26
+ }, (res) => {
27
+ let data = '';
28
+ res.on('data', (chunk) => { data += chunk; });
29
+ res.on('end', () => {
30
+ try {
31
+ const parsed = JSON.parse(data);
32
+ resolve({
33
+ code: parsed.code ?? 0,
34
+ message: parsed.message ?? 'ok',
35
+ data: parsed.data ?? null,
36
+ });
37
+ }
38
+ catch {
39
+ resolve({ code: 500, message: `Invalid response: ${data.substring(0, 200)}`, data: null });
40
+ }
41
+ });
42
+ });
43
+ req.on('error', (err) => {
44
+ resolve({ code: 500, message: `Request failed: ${err.message}`, data: null });
45
+ });
46
+ req.write(body);
47
+ req.end();
48
+ });
49
+ }
50
+ /**
51
+ * POST /api/v1/mcp/auth/login
52
+ */
53
+ export async function authLogin(email, password) {
54
+ const baseUrl = getBaseUrl();
55
+ const url = new URL('/api/v1/mcp/auth/login', baseUrl);
56
+ const md5Password = crypto.createHash('md5').update(password).digest('hex');
57
+ const body = JSON.stringify({ email, password: md5Password });
58
+ return new Promise((resolve) => {
59
+ const mod = url.protocol === 'https:' ? https : http;
60
+ const req = mod.request(url, {
61
+ method: 'POST',
62
+ headers: {
63
+ 'Content-Type': 'application/json',
64
+ 'Content-Length': Buffer.byteLength(body),
65
+ },
66
+ }, (res) => {
67
+ let data = '';
68
+ res.on('data', (chunk) => { data += chunk; });
69
+ res.on('end', () => {
70
+ try {
71
+ const parsed = JSON.parse(data);
72
+ resolve({
73
+ code: parsed.code ?? 0,
74
+ message: parsed.message ?? 'ok',
75
+ data: parsed.data ?? null,
76
+ });
77
+ }
78
+ catch {
79
+ resolve({ code: 500, message: `Invalid response: ${data.substring(0, 200)}`, data: null });
80
+ }
81
+ });
82
+ });
83
+ req.on('error', (err) => {
84
+ resolve({ code: 500, message: `Request failed: ${err.message}`, data: null });
85
+ });
86
+ req.write(body);
87
+ req.end();
88
+ });
89
+ }
90
+ /**
91
+ * GET /api/v1/mcp/auth/me
92
+ */
93
+ export async function authMe(profileName) {
94
+ const baseUrl = getBaseUrl();
95
+ const token = getToken(profileName);
96
+ if (!token) {
97
+ return { code: 401, message: 'Not logged in', data: null };
98
+ }
99
+ const url = new URL('/api/v1/mcp/auth/me', baseUrl);
100
+ return new Promise((resolve) => {
101
+ const mod = url.protocol === 'https:' ? https : http;
102
+ const req = mod.request(url, {
103
+ method: 'GET',
104
+ headers: {
105
+ 'Authorization': `Bearer ${token}`,
106
+ },
107
+ }, (res) => {
108
+ let data = '';
109
+ res.on('data', (chunk) => { data += chunk; });
110
+ res.on('end', () => {
111
+ try {
112
+ const parsed = JSON.parse(data);
113
+ resolve({
114
+ code: parsed.code ?? 0,
115
+ message: parsed.message ?? 'ok',
116
+ data: parsed.data ?? null,
117
+ });
118
+ }
119
+ catch {
120
+ resolve({ code: 500, message: `Invalid response: ${data.substring(0, 200)}`, data: null });
121
+ }
122
+ });
123
+ });
124
+ req.on('error', (err) => {
125
+ resolve({ code: 500, message: `Request failed: ${err.message}`, data: null });
126
+ });
127
+ req.end();
128
+ });
129
+ }
130
+ //# sourceMappingURL=exec.js.map