@lanonasis/cli 1.5.1 → 2.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.
@@ -1,6 +1,8 @@
1
1
  interface LoginOptions {
2
2
  email?: string;
3
3
  password?: string;
4
+ vendorKey?: string;
5
+ useWebAuth?: boolean;
4
6
  }
5
7
  export declare function loginCommand(options: LoginOptions): Promise<void>;
6
8
  export {};
@@ -1,12 +1,151 @@
1
1
  import chalk from 'chalk';
2
2
  import inquirer from 'inquirer';
3
3
  import ora from 'ora';
4
+ import open from 'open';
4
5
  import { apiClient } from '../utils/api.js';
5
6
  import { CLIConfig } from '../utils/config.js';
7
+ // Color scheme
8
+ const colors = {
9
+ primary: chalk.blue.bold,
10
+ success: chalk.green,
11
+ warning: chalk.yellow,
12
+ error: chalk.red,
13
+ info: chalk.cyan,
14
+ accent: chalk.magenta,
15
+ muted: chalk.gray,
16
+ highlight: chalk.white.bold
17
+ };
6
18
  export async function loginCommand(options) {
7
19
  const config = new CLIConfig();
8
20
  await config.init();
9
- console.log(chalk.blue.bold('🔐 Login to MaaS (Supabase Auth)'));
21
+ console.log(chalk.blue.bold('🔐 Onasis-Core Golden Contract Authentication'));
22
+ console.log(colors.info('━'.repeat(50)));
23
+ console.log();
24
+ // Enhanced authentication flow - check for vendor key first
25
+ if (options.vendorKey) {
26
+ await handleVendorKeyAuth(options.vendorKey, config);
27
+ return;
28
+ }
29
+ // Show authentication options
30
+ const authChoice = await inquirer.prompt([
31
+ {
32
+ type: 'list',
33
+ name: 'method',
34
+ message: 'Choose authentication method:',
35
+ choices: [
36
+ {
37
+ name: '🔑 Vendor Key (Recommended for API access)',
38
+ value: 'vendor'
39
+ },
40
+ {
41
+ name: '🌐 Web OAuth (Browser-based)',
42
+ value: 'oauth'
43
+ },
44
+ {
45
+ name: '⚙️ Username/Password (Direct credentials)',
46
+ value: 'credentials'
47
+ }
48
+ ]
49
+ }
50
+ ]);
51
+ switch (authChoice.method) {
52
+ case 'vendor':
53
+ await handleVendorKeyFlow(config);
54
+ break;
55
+ case 'oauth':
56
+ await handleOAuthFlow(config);
57
+ break;
58
+ case 'credentials':
59
+ await handleCredentialsFlow(options, config);
60
+ break;
61
+ }
62
+ }
63
+ async function handleVendorKeyAuth(vendorKey, config) {
64
+ const spinner = ora('Validating vendor key...').start();
65
+ try {
66
+ await config.setVendorKey(vendorKey);
67
+ // Test the vendor key with a health check
68
+ const response = await apiClient.get('/health');
69
+ spinner.succeed('Vendor key authentication successful');
70
+ console.log();
71
+ console.log(chalk.green('✓ Authenticated with vendor key'));
72
+ console.log(colors.info('Ready to use Onasis-Core services'));
73
+ }
74
+ catch (error) {
75
+ spinner.fail('Vendor key validation failed');
76
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
77
+ console.error(chalk.red('✖ Invalid vendor key:'), errorMessage);
78
+ process.exit(1);
79
+ }
80
+ }
81
+ async function handleVendorKeyFlow(config) {
82
+ console.log();
83
+ console.log(chalk.yellow('🔑 Vendor Key Authentication'));
84
+ console.log(chalk.gray('Vendor keys provide secure API access with format: pk_xxx.sk_xxx'));
85
+ console.log();
86
+ const { vendorKey } = await inquirer.prompt([
87
+ {
88
+ type: 'password',
89
+ name: 'vendorKey',
90
+ message: 'Enter your vendor key (pk_xxx.sk_xxx):',
91
+ mask: '*',
92
+ validate: (input) => {
93
+ if (!input)
94
+ return 'Vendor key is required';
95
+ if (!input.match(/^pk_[a-zA-Z0-9]+\.sk_[a-zA-Z0-9]+$/)) {
96
+ return 'Invalid format. Expected: pk_xxx.sk_xxx';
97
+ }
98
+ return true;
99
+ }
100
+ }
101
+ ]);
102
+ await handleVendorKeyAuth(vendorKey, config);
103
+ }
104
+ async function handleOAuthFlow(config) {
105
+ console.log();
106
+ console.log(chalk.yellow('🌐 Web OAuth Authentication'));
107
+ console.log(chalk.gray('This will open your browser for secure authentication'));
108
+ console.log();
109
+ const { proceed } = await inquirer.prompt([
110
+ {
111
+ type: 'confirm',
112
+ name: 'proceed',
113
+ message: 'Open browser for authentication?',
114
+ default: true
115
+ }
116
+ ]);
117
+ if (!proceed) {
118
+ console.log(chalk.yellow('Authentication cancelled'));
119
+ return;
120
+ }
121
+ const authUrl = `${config.getDiscoveredApiUrl()}/auth/cli-login`;
122
+ try {
123
+ console.log(colors.info('Opening browser...'));
124
+ await open(authUrl);
125
+ console.log();
126
+ console.log(colors.info('Please complete authentication in your browser'));
127
+ console.log(colors.muted(`If browser doesn't open, visit: ${authUrl}`));
128
+ // TODO: Implement OAuth callback handling or polling mechanism
129
+ const { token } = await inquirer.prompt([
130
+ {
131
+ type: 'input',
132
+ name: 'token',
133
+ message: 'Paste the authentication token from browser:'
134
+ }
135
+ ]);
136
+ if (token) {
137
+ await config.setToken(token);
138
+ console.log(chalk.green('✓ OAuth authentication successful'));
139
+ }
140
+ }
141
+ catch (error) {
142
+ console.error(chalk.red('✖ Failed to open browser'));
143
+ console.log(colors.muted(`Please visit manually: ${authUrl}`));
144
+ }
145
+ }
146
+ async function handleCredentialsFlow(options, config) {
147
+ console.log();
148
+ console.log(chalk.yellow('⚙️ Username/Password Authentication'));
10
149
  console.log();
11
150
  let { email, password } = options;
12
151
  // Get credentials if not provided
@@ -0,0 +1,33 @@
1
+ export interface CompletionData {
2
+ commands: Array<{
3
+ name: string;
4
+ description: string;
5
+ aliases?: string[];
6
+ subcommands?: Array<{
7
+ name: string;
8
+ description: string;
9
+ options?: Array<{
10
+ name: string;
11
+ description: string;
12
+ type: 'string' | 'boolean' | 'number' | 'choice';
13
+ choices?: string[];
14
+ required?: boolean;
15
+ }>;
16
+ }>;
17
+ }>;
18
+ globalOptions: Array<{
19
+ name: string;
20
+ description: string;
21
+ type: 'string' | 'boolean' | 'number' | 'choice';
22
+ choices?: string[];
23
+ }>;
24
+ contextualData: {
25
+ memoryTypes: string[];
26
+ outputFormats: string[];
27
+ sortOptions: string[];
28
+ authMethods: string[];
29
+ };
30
+ }
31
+ export declare function generateCompletionData(): Promise<CompletionData>;
32
+ export declare function completionCommand(): Promise<void>;
33
+ export declare function installCompletionsCommand(): Promise<void>;
@@ -0,0 +1,378 @@
1
+ import chalk from 'chalk';
2
+ import { CLIConfig } from '../utils/config.js';
3
+ import { apiClient } from '../utils/api.js';
4
+ // Color scheme
5
+ const colors = {
6
+ primary: chalk.blue.bold,
7
+ success: chalk.green,
8
+ warning: chalk.yellow,
9
+ error: chalk.red,
10
+ info: chalk.cyan,
11
+ accent: chalk.magenta,
12
+ muted: chalk.gray,
13
+ highlight: chalk.white.bold
14
+ };
15
+ export async function generateCompletionData() {
16
+ const config = new CLIConfig();
17
+ await config.init();
18
+ // Dynamic data that might come from API or config
19
+ let memoryTypes = ['context', 'project', 'knowledge', 'reference', 'personal', 'workflow'];
20
+ let topics = [];
21
+ try {
22
+ // Try to fetch dynamic data if authenticated
23
+ if (await config.isAuthenticated()) {
24
+ const topicsData = await apiClient.getTopics();
25
+ topics = topicsData.map(t => t.name);
26
+ }
27
+ }
28
+ catch {
29
+ // Ignore errors in completion generation
30
+ }
31
+ const completionData = {
32
+ commands: [
33
+ {
34
+ name: 'init',
35
+ description: 'Initialize CLI configuration',
36
+ subcommands: []
37
+ },
38
+ {
39
+ name: 'auth',
40
+ aliases: ['login'],
41
+ description: 'Authentication commands',
42
+ subcommands: [
43
+ {
44
+ name: 'login',
45
+ description: 'Login to your account',
46
+ options: [
47
+ { name: '--email', description: 'Email address', type: 'string' },
48
+ { name: '--password', description: 'Password', type: 'string' },
49
+ { name: '--vendor-key', description: 'Vendor key (pk_xxx.sk_xxx)', type: 'string' },
50
+ { name: '--oauth', description: 'Use OAuth flow', type: 'boolean' }
51
+ ]
52
+ },
53
+ {
54
+ name: 'logout',
55
+ description: 'Logout from your account',
56
+ options: []
57
+ },
58
+ {
59
+ name: 'status',
60
+ description: 'Show authentication status',
61
+ options: []
62
+ }
63
+ ]
64
+ },
65
+ {
66
+ name: 'memory',
67
+ aliases: ['mem'],
68
+ description: 'Memory management commands',
69
+ subcommands: [
70
+ {
71
+ name: 'list',
72
+ description: 'List memories',
73
+ options: [
74
+ { name: '--limit', description: 'Number of results', type: 'number' },
75
+ { name: '--offset', description: 'Results offset', type: 'number' },
76
+ { name: '--memory-type', description: 'Filter by memory type', type: 'choice', choices: memoryTypes },
77
+ { name: '--sort-by', description: 'Sort field', type: 'choice', choices: ['created_at', 'updated_at', 'last_accessed', 'access_count'] },
78
+ { name: '--sort-order', description: 'Sort order', type: 'choice', choices: ['asc', 'desc'] },
79
+ { name: '--tags', description: 'Filter by tags', type: 'string' }
80
+ ]
81
+ },
82
+ {
83
+ name: 'create',
84
+ description: 'Create a new memory',
85
+ options: [
86
+ { name: '--title', description: 'Memory title', type: 'string', required: true },
87
+ { name: '--content', description: 'Memory content', type: 'string', required: true },
88
+ { name: '--memory-type', description: 'Memory type', type: 'choice', choices: memoryTypes },
89
+ { name: '--tags', description: 'Comma-separated tags', type: 'string' },
90
+ { name: '--topic-id', description: 'Topic ID', type: 'string' }
91
+ ]
92
+ },
93
+ {
94
+ name: 'get',
95
+ description: 'Get a specific memory',
96
+ options: [
97
+ { name: 'id', description: 'Memory ID', type: 'string', required: true }
98
+ ]
99
+ },
100
+ {
101
+ name: 'update',
102
+ description: 'Update an existing memory',
103
+ options: [
104
+ { name: 'id', description: 'Memory ID', type: 'string', required: true },
105
+ { name: '--title', description: 'Memory title', type: 'string' },
106
+ { name: '--content', description: 'Memory content', type: 'string' },
107
+ { name: '--memory-type', description: 'Memory type', type: 'choice', choices: memoryTypes },
108
+ { name: '--tags', description: 'Comma-separated tags', type: 'string' }
109
+ ]
110
+ },
111
+ {
112
+ name: 'delete',
113
+ description: 'Delete a memory',
114
+ options: [
115
+ { name: 'id', description: 'Memory ID', type: 'string', required: true }
116
+ ]
117
+ },
118
+ {
119
+ name: 'search',
120
+ description: 'Search memories',
121
+ options: [
122
+ { name: 'query', description: 'Search query', type: 'string', required: true },
123
+ { name: '--memory-types', description: 'Filter by memory types', type: 'string' },
124
+ { name: '--limit', description: 'Number of results', type: 'number' },
125
+ { name: '--threshold', description: 'Relevance threshold', type: 'number' }
126
+ ]
127
+ },
128
+ {
129
+ name: 'stats',
130
+ description: 'Show memory statistics',
131
+ options: []
132
+ },
133
+ {
134
+ name: 'bulk-delete',
135
+ description: 'Delete multiple memories',
136
+ options: [
137
+ { name: '--ids', description: 'Comma-separated memory IDs', type: 'string', required: true }
138
+ ]
139
+ }
140
+ ]
141
+ },
142
+ {
143
+ name: 'topic',
144
+ aliases: ['topics'],
145
+ description: 'Topic management commands',
146
+ subcommands: [
147
+ {
148
+ name: 'list',
149
+ description: 'List topics',
150
+ options: []
151
+ },
152
+ {
153
+ name: 'create',
154
+ description: 'Create a new topic',
155
+ options: [
156
+ { name: '--name', description: 'Topic name', type: 'string', required: true },
157
+ { name: '--description', description: 'Topic description', type: 'string' },
158
+ { name: '--color', description: 'Topic color', type: 'string' },
159
+ { name: '--icon', description: 'Topic icon', type: 'string' }
160
+ ]
161
+ },
162
+ {
163
+ name: 'get',
164
+ description: 'Get a specific topic',
165
+ options: [
166
+ { name: 'id', description: 'Topic ID', type: 'string', required: true }
167
+ ]
168
+ },
169
+ {
170
+ name: 'update',
171
+ description: 'Update an existing topic',
172
+ options: [
173
+ { name: 'id', description: 'Topic ID', type: 'string', required: true },
174
+ { name: '--name', description: 'Topic name', type: 'string' },
175
+ { name: '--description', description: 'Topic description', type: 'string' },
176
+ { name: '--color', description: 'Topic color', type: 'string' }
177
+ ]
178
+ },
179
+ {
180
+ name: 'delete',
181
+ description: 'Delete a topic',
182
+ options: [
183
+ { name: 'id', description: 'Topic ID', type: 'string', required: true }
184
+ ]
185
+ }
186
+ ]
187
+ },
188
+ {
189
+ name: 'config',
190
+ description: 'Configuration management',
191
+ subcommands: [
192
+ {
193
+ name: 'get',
194
+ description: 'Get configuration value',
195
+ options: [
196
+ { name: 'key', description: 'Configuration key', type: 'string', required: true }
197
+ ]
198
+ },
199
+ {
200
+ name: 'set',
201
+ description: 'Set configuration value',
202
+ options: [
203
+ { name: 'key', description: 'Configuration key', type: 'string', required: true },
204
+ { name: 'value', description: 'Configuration value', type: 'string', required: true }
205
+ ]
206
+ },
207
+ {
208
+ name: 'list',
209
+ description: 'List all configuration',
210
+ options: []
211
+ },
212
+ {
213
+ name: 'reset',
214
+ description: 'Reset configuration',
215
+ options: [
216
+ { name: '--confirm', description: 'Confirm reset', type: 'boolean' }
217
+ ]
218
+ }
219
+ ]
220
+ },
221
+ {
222
+ name: 'api-keys',
223
+ description: 'API key management',
224
+ subcommands: [
225
+ {
226
+ name: 'list',
227
+ description: 'List API keys',
228
+ options: []
229
+ },
230
+ {
231
+ name: 'create',
232
+ description: 'Create a new API key',
233
+ options: [
234
+ { name: '--name', description: 'API key name', type: 'string', required: true },
235
+ { name: '--scope', description: 'API key scope', type: 'string' },
236
+ { name: '--expires', description: 'Expiration date', type: 'string' }
237
+ ]
238
+ },
239
+ {
240
+ name: 'revoke',
241
+ description: 'Revoke an API key',
242
+ options: [
243
+ { name: 'id', description: 'API key ID', type: 'string', required: true }
244
+ ]
245
+ },
246
+ {
247
+ name: 'rotate',
248
+ description: 'Rotate an API key',
249
+ options: [
250
+ { name: 'id', description: 'API key ID', type: 'string', required: true }
251
+ ]
252
+ }
253
+ ]
254
+ },
255
+ {
256
+ name: 'mcp',
257
+ description: 'Model Context Protocol commands',
258
+ subcommands: [
259
+ {
260
+ name: 'status',
261
+ description: 'Show MCP server status',
262
+ options: []
263
+ },
264
+ {
265
+ name: 'connect',
266
+ description: 'Connect to MCP server',
267
+ options: [
268
+ { name: '--remote', description: 'Use remote server', type: 'boolean' },
269
+ { name: '--local', description: 'Use local server', type: 'boolean' }
270
+ ]
271
+ },
272
+ {
273
+ name: 'disconnect',
274
+ description: 'Disconnect from MCP server',
275
+ options: []
276
+ },
277
+ {
278
+ name: 'servers',
279
+ description: 'List MCP servers',
280
+ options: []
281
+ },
282
+ {
283
+ name: 'tools',
284
+ description: 'List available tools',
285
+ options: []
286
+ },
287
+ {
288
+ name: 'resources',
289
+ description: 'List available resources',
290
+ options: []
291
+ }
292
+ ]
293
+ },
294
+ {
295
+ name: 'dashboard',
296
+ description: 'Dashboard management',
297
+ subcommands: [
298
+ {
299
+ name: 'status',
300
+ description: 'Check dashboard status',
301
+ options: []
302
+ },
303
+ {
304
+ name: 'logs',
305
+ description: 'View dashboard logs',
306
+ options: []
307
+ },
308
+ {
309
+ name: 'open',
310
+ description: 'Open dashboard in browser',
311
+ options: []
312
+ }
313
+ ]
314
+ },
315
+ {
316
+ name: 'status',
317
+ description: 'Show overall system status',
318
+ subcommands: []
319
+ },
320
+ {
321
+ name: 'health',
322
+ aliases: ['check'],
323
+ description: 'Comprehensive system health check',
324
+ subcommands: []
325
+ }
326
+ ],
327
+ globalOptions: [
328
+ { name: '--help', description: 'Show help information', type: 'boolean' },
329
+ { name: '--version', description: 'Show version information', type: 'boolean' },
330
+ { name: '--verbose', description: 'Enable verbose logging', type: 'boolean' },
331
+ { name: '--output', description: 'Output format', type: 'choice', choices: ['table', 'json', 'yaml', 'csv'] },
332
+ { name: '--api-url', description: 'Override API URL', type: 'string' },
333
+ { name: '--no-mcp', description: 'Disable MCP and use direct API', type: 'boolean' }
334
+ ],
335
+ contextualData: {
336
+ memoryTypes,
337
+ outputFormats: ['table', 'json', 'yaml', 'csv'],
338
+ sortOptions: ['created_at', 'updated_at', 'last_accessed', 'access_count'],
339
+ authMethods: ['vendor_key', 'oauth', 'credentials']
340
+ }
341
+ };
342
+ return completionData;
343
+ }
344
+ export async function completionCommand() {
345
+ try {
346
+ const data = await generateCompletionData();
347
+ console.log(JSON.stringify(data, null, 2));
348
+ }
349
+ catch (error) {
350
+ console.error(chalk.red('✖ Failed to generate completion data:'), error instanceof Error ? error.message : String(error));
351
+ process.exit(1);
352
+ }
353
+ }
354
+ export async function installCompletionsCommand() {
355
+ console.log(chalk.blue.bold('🔧 Installing Shell Completions'));
356
+ console.log(colors.info('═'.repeat(40)));
357
+ console.log();
358
+ console.log(chalk.yellow('📋 Installation Instructions:'));
359
+ console.log();
360
+ console.log(chalk.white('Bash:'));
361
+ console.log(chalk.gray(' # Add to ~/.bashrc or ~/.bash_profile:'));
362
+ console.log(chalk.cyan(' source <(lanonasis --completion bash)'));
363
+ console.log();
364
+ console.log(chalk.white('Zsh:'));
365
+ console.log(chalk.gray(' # Add to ~/.zshrc:'));
366
+ console.log(chalk.cyan(' source <(lanonasis --completion zsh)'));
367
+ console.log(chalk.gray(' # Or for Oh My Zsh, create ~/.oh-my-zsh/completions/_lanonasis'));
368
+ console.log();
369
+ console.log(chalk.white('Fish:'));
370
+ console.log(chalk.gray(' # Add to ~/.config/fish/config.fish:'));
371
+ console.log(chalk.cyan(' lanonasis --completion fish | source'));
372
+ console.log(chalk.gray(' # Or save to ~/.config/fish/completions/lanonasis.fish'));
373
+ console.log();
374
+ console.log(colors.info('💡 Completions support all command aliases:'));
375
+ console.log(chalk.gray(' • lanonasis, onasis, memory, maas'));
376
+ console.log();
377
+ console.log(colors.success('✅ Run the appropriate command above for your shell'));
378
+ }
@@ -0,0 +1,19 @@
1
+ export declare class UserGuidanceSystem {
2
+ private config;
3
+ private steps;
4
+ constructor();
5
+ private initializeSteps;
6
+ runGuidedSetup(): Promise<void>;
7
+ private assessCurrentStatus;
8
+ private markStepCompleted;
9
+ private executeStep;
10
+ private initializeConfig;
11
+ private setupAuthentication;
12
+ private verifyConnection;
13
+ private createFirstMemory;
14
+ private exploreFeatures;
15
+ private setupProductivity;
16
+ private showCompletionSummary;
17
+ }
18
+ export declare function guideCommand(): Promise<void>;
19
+ export declare function quickStartCommand(): Promise<void>;