skedyul 1.0.2 → 1.0.3

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/dist/.build-stamp CHANGED
@@ -1 +1 @@
1
- 1771999780767
1
+ 1772014398145
@@ -4,56 +4,70 @@ exports.authCommand = authCommand;
4
4
  const login_1 = require("./login");
5
5
  const logout_1 = require("./logout");
6
6
  const status_1 = require("./status");
7
+ const use_1 = require("./use");
8
+ const list_1 = require("./list");
7
9
  function printUsage() {
8
10
  console.log(`
9
11
  SKEDYUL AUTH - Authentication Commands
10
12
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
11
13
 
12
- Manage your Skedyul CLI authentication.
14
+ Manage your Skedyul CLI authentication with multiple profiles.
13
15
 
14
16
  USAGE
15
17
  $ skedyul auth <command> [options]
16
18
 
17
19
  COMMANDS
18
20
  login Authenticate with Skedyul via browser OAuth
19
- logout Clear stored credentials
21
+ logout Clear stored credentials (from active or specified profile)
20
22
  status Show current authentication status and linked workplaces
23
+ use Switch to a different profile
24
+ list List all saved profiles
25
+
26
+ PROFILES
27
+ The CLI supports multiple authentication profiles, allowing you to easily
28
+ switch between different environments (local, staging, production).
29
+
30
+ Each profile stores:
31
+ • Server URL (e.g., http://localhost:3000, https://admin.skedyul.it)
32
+ • Authentication token
33
+ • User information (email, username)
21
34
 
22
35
  HOW AUTHENTICATION WORKS
23
- 1. Run 'skedyul auth login'
36
+ 1. Run 'skedyul auth login --server <url>'
24
37
  2. Browser opens to Skedyul login page
25
38
  3. After login, you're redirected back to CLI
26
- 4. Credentials saved to ~/.skedyul/credentials.json
27
-
28
- Your CLI token is used for:
29
- • Linking projects to workplaces
30
- • Getting scoped API tokens for tool testing
31
- • Managing local development environments
39
+ 4. Credentials saved to ~/.skedyul/profiles.json
40
+ 5. Profile is auto-named based on server (local, staging, production)
32
41
 
33
42
  EXAMPLES
34
- # Login to production Skedyul
43
+ # Login to production (creates "production" profile)
35
44
  $ skedyul auth login
36
45
 
37
- # Login to a specific server
46
+ # Login to local dev (creates "local" profile)
38
47
  $ skedyul auth login --server http://localhost:3000
39
48
 
40
- # Check authentication status
41
- $ skedyul auth status
49
+ # Login with custom profile name
50
+ $ skedyul auth login --server http://localhost:3000 --profile my-local
42
51
 
43
- # Logout and clear credentials
44
- $ skedyul auth logout
52
+ # List all profiles
53
+ $ skedyul auth list
45
54
 
46
- SERVER CONFIGURATION
47
- Default server: https://admin.skedyul.it
55
+ # Switch between profiles
56
+ $ skedyul auth use local
57
+ $ skedyul auth use production
48
58
 
49
- Override with:
50
- --server flag on any command
51
- • .skedyul.local.json in project root:
52
- { "serverUrl": "http://localhost:3000" }
59
+ # Check current status
60
+ $ skedyul auth status
61
+
62
+ # Logout from specific profile
63
+ $ skedyul auth logout --profile local
64
+
65
+ # Logout from all profiles
66
+ $ skedyul auth logout --all
53
67
 
54
68
  CREDENTIAL STORAGE
55
- Credentials: ~/.skedyul/credentials.json
56
- Config: ~/.skedyul/config.json
69
+ Profiles: ~/.skedyul/profiles.json
70
+ Config: ~/.skedyul/config.json
57
71
 
58
72
  Credentials are stored with restrictive permissions (600).
59
73
  `);
@@ -75,6 +89,12 @@ async function authCommand(args) {
75
89
  case 'status':
76
90
  await (0, status_1.statusCommand)(subArgs);
77
91
  break;
92
+ case 'use':
93
+ await (0, use_1.useCommand)(subArgs);
94
+ break;
95
+ case 'list':
96
+ await (0, list_1.listCommand)(subArgs);
97
+ break;
78
98
  default:
79
99
  console.error(`Unknown auth command: ${subCommand}`);
80
100
  console.error(`Run 'skedyul auth --help' for usage information.`);
@@ -0,0 +1 @@
1
+ export declare function listCommand(args: string[]): Promise<void>;
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.listCommand = listCommand;
4
+ const utils_1 = require("../../utils");
5
+ const auth_1 = require("../../utils/auth");
6
+ function printHelp() {
7
+ console.log(`
8
+ skedyul auth list - List all authentication profiles
9
+
10
+ Usage:
11
+ skedyul auth list [options]
12
+
13
+ Options:
14
+ --help, -h Show this help message
15
+
16
+ Output:
17
+ Lists all saved profiles with their server URLs and email addresses.
18
+ The active profile is marked with an asterisk (*).
19
+
20
+ Examples:
21
+ skedyul auth list
22
+ `);
23
+ }
24
+ async function listCommand(args) {
25
+ const { flags } = (0, utils_1.parseArgs)(args);
26
+ if (flags.help || flags.h) {
27
+ printHelp();
28
+ return;
29
+ }
30
+ const profiles = (0, auth_1.listProfiles)();
31
+ if (profiles.length === 0) {
32
+ console.log('No profiles found.');
33
+ console.log('');
34
+ console.log('Run "skedyul auth login" to create a profile.');
35
+ return;
36
+ }
37
+ console.log('Authentication Profiles');
38
+ console.log('─'.repeat(60));
39
+ console.log('');
40
+ for (const { name, profile, isActive, isExpired } of profiles) {
41
+ const marker = isActive ? '*' : ' ';
42
+ const expiredTag = isExpired ? ' [EXPIRED]' : '';
43
+ console.log(`${marker} ${name}${expiredTag}`);
44
+ console.log(` Server: ${profile.serverUrl}`);
45
+ console.log(` Email: ${profile.email}`);
46
+ console.log('');
47
+ }
48
+ console.log('─'.repeat(60));
49
+ console.log('* = active profile');
50
+ console.log('');
51
+ console.log('Commands:');
52
+ console.log(' skedyul auth use <profile> Switch to a profile');
53
+ console.log(' skedyul auth login Add a new profile');
54
+ console.log(' skedyul auth logout --profile <name> Remove a profile');
55
+ }
@@ -11,15 +11,23 @@ Usage:
11
11
  skedyul auth login [options]
12
12
 
13
13
  Options:
14
- --server, -s Skedyul server URL (default: https://app.skedyul.com)
14
+ --server, -s Skedyul server URL (default: https://admin.skedyul.it)
15
+ --profile, -p Profile name to save credentials under
16
+ (auto-generated from server URL if not provided)
15
17
  --help, -h Show this help message
16
18
 
17
19
  Examples:
18
- # Login to production Skedyul
20
+ # Login to production Skedyul (profile: production)
19
21
  skedyul auth login
20
22
 
21
- # Login to a local Skedyul instance
23
+ # Login to a local Skedyul instance (profile: local)
22
24
  skedyul auth login --server http://localhost:3000
25
+
26
+ # Login with a custom profile name
27
+ skedyul auth login --server http://localhost:3000 --profile my-local
28
+
29
+ # Login to staging with custom profile
30
+ skedyul auth login --server https://staging.skedyul.it --profile staging
23
31
  `);
24
32
  }
25
33
  async function loginCommand(args) {
@@ -28,21 +36,31 @@ async function loginCommand(args) {
28
36
  printHelp();
29
37
  return;
30
38
  }
31
- // Check if already logged in
32
- const existingCredentials = (0, auth_1.getCredentials)();
33
- if (existingCredentials) {
34
- console.log(`Already logged in as ${existingCredentials.email}`);
35
- console.log(`Server: ${existingCredentials.serverUrl}`);
36
- console.log(`\nRun 'skedyul auth logout' to log out first.`);
37
- return;
38
- }
39
- // Get server URL
40
39
  const serverUrl = (0, auth_1.getServerUrl)((flags.server || flags.s));
41
- console.log(`Authenticating with ${serverUrl}...\n`);
40
+ const requestedProfile = (flags.profile || flags.p);
41
+ const profilesFile = (0, auth_1.getProfiles)();
42
+ let profileName;
43
+ if (requestedProfile) {
44
+ profileName = requestedProfile;
45
+ const existingProfile = (0, auth_1.getProfile)(profileName);
46
+ if (existingProfile) {
47
+ console.log(`Profile "${profileName}" already exists.`);
48
+ console.log(` Email: ${existingProfile.email}`);
49
+ console.log(` Server: ${existingProfile.serverUrl}`);
50
+ console.log(`\nTo switch to this profile, run: skedyul auth use ${profileName}`);
51
+ console.log(`To logout and re-login, run: skedyul auth logout --profile ${profileName}`);
52
+ return;
53
+ }
54
+ }
55
+ else {
56
+ const baseName = (0, auth_1.generateProfileName)(serverUrl);
57
+ profileName = (0, auth_1.ensureUniqueProfileName)(baseName, profilesFile.profiles);
58
+ }
59
+ console.log(`Authenticating with ${serverUrl}...`);
60
+ console.log(`Profile: ${profileName}\n`);
42
61
  try {
43
62
  const result = await (0, auth_1.startOAuthCallback)(serverUrl);
44
- // Save credentials
45
- (0, auth_1.saveCredentials)({
63
+ const savedProfileName = (0, auth_1.saveCredentials)({
46
64
  token: result.token,
47
65
  userId: result.userId,
48
66
  username: result.username,
@@ -50,13 +68,12 @@ async function loginCommand(args) {
50
68
  serverUrl,
51
69
  expiresAt: result.expiresAt,
52
70
  createdAt: new Date().toISOString(),
53
- });
54
- // Save server as default
55
- (0, auth_1.saveConfig)({ defaultServer: serverUrl });
56
- console.log(`\n✓ Logged in as ${result.email}`);
57
- console.log(` Username: ${result.username}`);
71
+ }, profileName);
72
+ console.log(`\nLogged in as ${result.email}`);
73
+ console.log(` Profile: ${savedProfileName}`);
58
74
  console.log(` Server: ${serverUrl}`);
59
- console.log(` Credentials saved to ~/.skedyul/credentials.json`);
75
+ console.log(` Credentials saved to ~/.skedyul/profiles.json`);
76
+ console.log(`\nThis profile is now active. To switch profiles, run: skedyul auth use <profile>`);
60
77
  }
61
78
  catch (error) {
62
79
  console.error(`\nAuthentication failed: ${error instanceof Error ? error.message : String(error)}`);
@@ -11,9 +11,19 @@ Usage:
11
11
  skedyul auth logout [options]
12
12
 
13
13
  Options:
14
- --help, -h Show this help message
14
+ --profile, -p Logout from a specific profile (default: active profile)
15
+ --all Logout from all profiles
16
+ --help, -h Show this help message
15
17
 
16
- This command clears your stored credentials from ~/.skedyul/credentials.json
18
+ Examples:
19
+ # Logout from active profile
20
+ skedyul auth logout
21
+
22
+ # Logout from a specific profile
23
+ skedyul auth logout --profile local
24
+
25
+ # Logout from all profiles
26
+ skedyul auth logout --all
17
27
  `);
18
28
  }
19
29
  async function logoutCommand(args) {
@@ -22,12 +32,70 @@ async function logoutCommand(args) {
22
32
  printHelp();
23
33
  return;
24
34
  }
25
- const credentials = (0, auth_1.getCredentials)();
26
- if (!credentials) {
27
- console.log('Not logged in.');
35
+ if (flags.all) {
36
+ const profiles = (0, auth_1.listProfiles)();
37
+ if (profiles.length === 0) {
38
+ console.log('No profiles to logout from.');
39
+ return;
40
+ }
41
+ (0, auth_1.clearAllProfiles)();
42
+ console.log(`Logged out from ${profiles.length} profile(s):`);
43
+ for (const { name, profile } of profiles) {
44
+ console.log(` - ${name} (${profile.email})`);
45
+ }
46
+ console.log('');
47
+ console.log('All credentials removed from ~/.skedyul/profiles.json');
48
+ return;
49
+ }
50
+ const profileName = (flags.profile || flags.p);
51
+ const targetProfile = profileName ?? (0, auth_1.getActiveProfileName)();
52
+ if (!targetProfile) {
53
+ console.log('No active profile. Nothing to logout from.');
54
+ console.log('');
55
+ const profiles = (0, auth_1.listProfiles)();
56
+ if (profiles.length > 0) {
57
+ console.log('Available profiles:');
58
+ for (const { name, profile } of profiles) {
59
+ console.log(` - ${name} (${profile.serverUrl})`);
60
+ }
61
+ console.log('');
62
+ console.log('Use --profile <name> to logout from a specific profile.');
63
+ }
28
64
  return;
29
65
  }
30
- (0, auth_1.clearCredentials)();
31
- console.log(`✓ Logged out from ${credentials.email}`);
32
- console.log(` Credentials removed from ~/.skedyul/credentials.json`);
66
+ const profile = (0, auth_1.getProfile)(targetProfile);
67
+ if (!profile) {
68
+ console.error(`Profile "${targetProfile}" not found.`);
69
+ console.error('');
70
+ const profiles = (0, auth_1.listProfiles)();
71
+ if (profiles.length > 0) {
72
+ console.error('Available profiles:');
73
+ for (const { name, profile: p } of profiles) {
74
+ console.error(` - ${name} (${p.serverUrl})`);
75
+ }
76
+ }
77
+ process.exit(1);
78
+ }
79
+ const deleted = (0, auth_1.deleteProfile)(targetProfile);
80
+ if (deleted) {
81
+ console.log(`Logged out from profile: ${targetProfile}`);
82
+ console.log(` Email: ${profile.email}`);
83
+ console.log(` Server: ${profile.serverUrl}`);
84
+ console.log('');
85
+ console.log('Credentials removed from ~/.skedyul/profiles.json');
86
+ const remainingProfiles = (0, auth_1.listProfiles)();
87
+ const newActive = remainingProfiles.find((p) => p.isActive);
88
+ if (newActive) {
89
+ console.log('');
90
+ console.log(`Active profile is now: ${newActive.name}`);
91
+ }
92
+ else if (remainingProfiles.length > 0) {
93
+ console.log('');
94
+ console.log('No active profile. Use "skedyul auth use <profile>" to set one.');
95
+ }
96
+ }
97
+ else {
98
+ console.error(`Failed to logout from profile: ${targetProfile}`);
99
+ process.exit(1);
100
+ }
33
101
  }
@@ -49,9 +49,8 @@ Options:
49
49
  --help, -h Show this help message
50
50
 
51
51
  Shows:
52
- - Current logged in user
53
- - Server URL
54
- - Token expiration
52
+ - Active profile and credentials
53
+ - All available profiles
55
54
  - Linked workplaces (from .skedyul/links/)
56
55
  `);
57
56
  }
@@ -61,40 +60,65 @@ async function statusCommand(args) {
61
60
  printHelp();
62
61
  return;
63
62
  }
64
- const credentials = (0, auth_1.getCredentials)();
65
63
  console.log('Skedyul CLI Status');
66
- console.log(''.repeat(40));
67
- if (!credentials) {
68
- console.log('\nAuthentication: Not logged in');
69
- console.log(`\nRun 'skedyul auth login' to authenticate.`);
70
- return;
64
+ console.log(''.repeat(60));
65
+ const activeProfileName = (0, auth_1.getActiveProfileName)();
66
+ const credentials = (0, auth_1.getCredentials)();
67
+ const profiles = (0, auth_1.listProfiles)();
68
+ console.log('');
69
+ console.log('ACTIVE PROFILE');
70
+ console.log('─'.repeat(60));
71
+ if (!activeProfileName || !credentials) {
72
+ console.log(' Not logged in');
73
+ console.log('');
74
+ console.log(` Run 'skedyul auth login' to authenticate.`);
71
75
  }
72
- console.log('\nAuthentication:');
73
- console.log(` Email: ${credentials.email}`);
74
- console.log(` Username: ${credentials.username}`);
75
- console.log(` Server: ${credentials.serverUrl}`);
76
- if (credentials.expiresAt) {
77
- const expiresAt = new Date(credentials.expiresAt);
78
- const now = new Date();
79
- if (expiresAt < now) {
80
- console.log(` Token: Expired`);
76
+ else {
77
+ console.log(` Profile: ${activeProfileName}`);
78
+ console.log(` Email: ${credentials.email}`);
79
+ console.log(` Username: ${credentials.username}`);
80
+ console.log(` Server: ${credentials.serverUrl}`);
81
+ if (credentials.expiresAt) {
82
+ const expiresAt = new Date(credentials.expiresAt);
83
+ const now = new Date();
84
+ if (expiresAt < now) {
85
+ console.log(` Token: EXPIRED`);
86
+ }
87
+ else {
88
+ const diffMs = expiresAt.getTime() - now.getTime();
89
+ const diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24));
90
+ const diffHours = Math.floor((diffMs % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
91
+ console.log(` Token: Valid (expires in ${diffDays}d ${diffHours}h)`);
92
+ }
81
93
  }
82
94
  else {
83
- const diffMs = expiresAt.getTime() - now.getTime();
84
- const diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24));
85
- const diffHours = Math.floor((diffMs % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
86
- console.log(` Token: Valid (expires in ${diffDays}d ${diffHours}h)`);
95
+ console.log(` Token: Valid (no expiration)`);
87
96
  }
88
97
  }
98
+ console.log('');
99
+ console.log('ALL PROFILES');
100
+ console.log('─'.repeat(60));
101
+ if (profiles.length === 0) {
102
+ console.log(' No profiles saved');
103
+ }
89
104
  else {
90
- console.log(` Token: Valid (no expiration)`);
105
+ for (const { name, profile, isActive, isExpired } of profiles) {
106
+ const marker = isActive ? '*' : ' ';
107
+ const expiredTag = isExpired ? ' [EXPIRED]' : '';
108
+ console.log(` ${marker} ${name}${expiredTag}`);
109
+ console.log(` Server: ${profile.serverUrl}`);
110
+ console.log(` Email: ${profile.email}`);
111
+ }
112
+ console.log('');
113
+ console.log(' * = active profile');
91
114
  }
92
- // Check for linked workplaces in current project
93
115
  const linksDir = path.join(process.cwd(), '.skedyul', 'links');
116
+ console.log('');
117
+ console.log('LINKED WORKPLACES (this project)');
118
+ console.log('─'.repeat(60));
94
119
  if (fs.existsSync(linksDir)) {
95
120
  const linkFiles = fs.readdirSync(linksDir).filter((f) => f.endsWith('.json'));
96
121
  if (linkFiles.length > 0) {
97
- console.log('\nLinked Workplaces (this project):');
98
122
  for (const file of linkFiles) {
99
123
  const subdomain = file.replace('.json', '');
100
124
  try {
@@ -108,11 +132,18 @@ async function statusCommand(args) {
108
132
  }
109
133
  }
110
134
  else {
111
- console.log('\nNo workplaces linked in this project.');
135
+ console.log(' No workplaces linked');
112
136
  }
113
137
  }
114
138
  else {
115
- console.log('\nNo workplaces linked in this project.');
139
+ console.log(' No workplaces linked');
116
140
  }
117
- console.log(`\nRun 'skedyul dev link --workplace <subdomain>' to link a workplace.`);
141
+ console.log('');
142
+ console.log('═'.repeat(60));
143
+ console.log('');
144
+ console.log('Commands:');
145
+ console.log(' skedyul auth login Add a new profile');
146
+ console.log(' skedyul auth use <profile> Switch active profile');
147
+ console.log(' skedyul auth list List all profiles');
148
+ console.log(' skedyul dev link --workplace Link a workplace');
118
149
  }
@@ -0,0 +1 @@
1
+ export declare function useCommand(args: string[]): Promise<void>;
@@ -0,0 +1,75 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useCommand = useCommand;
4
+ const utils_1 = require("../../utils");
5
+ const auth_1 = require("../../utils/auth");
6
+ function printHelp() {
7
+ console.log(`
8
+ skedyul auth use - Switch to a different profile
9
+
10
+ Usage:
11
+ skedyul auth use <profile-name>
12
+
13
+ Arguments:
14
+ <profile-name> Name of the profile to switch to
15
+
16
+ Options:
17
+ --help, -h Show this help message
18
+
19
+ Examples:
20
+ # Switch to local profile
21
+ skedyul auth use local
22
+
23
+ # Switch to production profile
24
+ skedyul auth use production
25
+
26
+ # List available profiles first
27
+ skedyul auth list
28
+ `);
29
+ }
30
+ async function useCommand(args) {
31
+ const { flags, positional } = (0, utils_1.parseArgs)(args);
32
+ if (flags.help || flags.h) {
33
+ printHelp();
34
+ return;
35
+ }
36
+ const profileName = positional[0];
37
+ if (!profileName) {
38
+ console.error('Error: Profile name is required');
39
+ console.error('');
40
+ const profiles = (0, auth_1.listProfiles)();
41
+ if (profiles.length > 0) {
42
+ console.error('Available profiles:');
43
+ for (const { name, profile, isActive } of profiles) {
44
+ const marker = isActive ? '*' : ' ';
45
+ console.error(` ${marker} ${name} (${profile.serverUrl})`);
46
+ }
47
+ }
48
+ else {
49
+ console.error('No profiles found. Run "skedyul auth login" to create one.');
50
+ }
51
+ process.exit(1);
52
+ }
53
+ const profile = (0, auth_1.getProfile)(profileName);
54
+ if (!profile) {
55
+ console.error(`Error: Profile "${profileName}" not found or expired`);
56
+ console.error('');
57
+ const profiles = (0, auth_1.listProfiles)();
58
+ if (profiles.length > 0) {
59
+ console.error('Available profiles:');
60
+ for (const { name, profile: p, isActive } of profiles) {
61
+ const marker = isActive ? '*' : ' ';
62
+ console.error(` ${marker} ${name} (${p.serverUrl})`);
63
+ }
64
+ }
65
+ process.exit(1);
66
+ }
67
+ const success = (0, auth_1.setActiveProfile)(profileName);
68
+ if (!success) {
69
+ console.error(`Error: Failed to switch to profile "${profileName}"`);
70
+ process.exit(1);
71
+ }
72
+ console.log(`Switched to profile: ${profileName}`);
73
+ console.log(` Server: ${profile.serverUrl}`);
74
+ console.log(` Email: ${profile.email}`);
75
+ }
@@ -0,0 +1 @@
1
+ export declare function invokeRemoteCommand(args: string[]): Promise<void>;