seamless-cli 0.5.2 → 0.7.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 (59) hide show
  1. package/README.md +171 -0
  2. package/dist/commands/adminShared.js +23 -0
  3. package/dist/commands/adminShared.js.map +1 -0
  4. package/dist/commands/config.js +187 -0
  5. package/dist/commands/config.js.map +1 -0
  6. package/dist/commands/help.js +98 -0
  7. package/dist/commands/help.js.map +1 -1
  8. package/dist/commands/init.js +182 -26
  9. package/dist/commands/init.js.map +1 -1
  10. package/dist/commands/login.js +86 -0
  11. package/dist/commands/login.js.map +1 -0
  12. package/dist/commands/logout.js +43 -0
  13. package/dist/commands/logout.js.map +1 -0
  14. package/dist/commands/org.js +249 -0
  15. package/dist/commands/org.js.map +1 -0
  16. package/dist/commands/profile.js +150 -0
  17. package/dist/commands/profile.js.map +1 -0
  18. package/dist/commands/sessions.js +112 -0
  19. package/dist/commands/sessions.js.map +1 -0
  20. package/dist/commands/users.js +147 -0
  21. package/dist/commands/users.js.map +1 -0
  22. package/dist/commands/verify.js +133 -9
  23. package/dist/commands/verify.js.map +1 -1
  24. package/dist/commands/whoami.js +29 -0
  25. package/dist/commands/whoami.js.map +1 -0
  26. package/dist/core/admin.js +142 -0
  27. package/dist/core/admin.js.map +1 -0
  28. package/dist/core/args.js +19 -0
  29. package/dist/core/args.js.map +1 -0
  30. package/dist/core/authClient.js +113 -0
  31. package/dist/core/authClient.js.map +1 -0
  32. package/dist/core/config.js +146 -0
  33. package/dist/core/config.js.map +1 -0
  34. package/dist/core/http.js +34 -0
  35. package/dist/core/http.js.map +1 -0
  36. package/dist/core/images.js +1 -1
  37. package/dist/core/keychain.js +112 -0
  38. package/dist/core/keychain.js.map +1 -0
  39. package/dist/core/loginFlow.js +143 -0
  40. package/dist/core/loginFlow.js.map +1 -0
  41. package/dist/core/output.js +46 -0
  42. package/dist/core/output.js.map +1 -1
  43. package/dist/core/portal.js +74 -0
  44. package/dist/core/portal.js.map +1 -0
  45. package/dist/core/session.js +30 -0
  46. package/dist/core/session.js.map +1 -0
  47. package/dist/core/sessions.js +41 -0
  48. package/dist/core/sessions.js.map +1 -0
  49. package/dist/core/systemConfig.js +125 -0
  50. package/dist/core/systemConfig.js.map +1 -0
  51. package/dist/generators/config/config.js +30 -15
  52. package/dist/generators/config/config.js.map +1 -1
  53. package/dist/index.js +51 -3
  54. package/dist/index.js.map +1 -1
  55. package/dist/prompts/appSelect.js +41 -0
  56. package/dist/prompts/appSelect.js.map +1 -0
  57. package/dist/prompts/projectSetup.js +26 -0
  58. package/dist/prompts/projectSetup.js.map +1 -1
  59. package/package.json +13 -2
@@ -0,0 +1,249 @@
1
+ import { confirm, isCancel } from "@clack/prompts";
2
+ import kleur from "kleur";
3
+ import { extractFlag } from "../core/args.js";
4
+ import { createAuthClient } from "../core/authClient.js";
5
+ import { addMember, createOrg, getOrg, listMembers, listOrgs, removeMember, updateMember, updateOrg, } from "../core/admin.js";
6
+ import { parseList, reportAdminError } from "./adminShared.js";
7
+ export async function runOrg(args) {
8
+ if (args[0] === "members") {
9
+ await runOrgMembers(args.slice(1));
10
+ return;
11
+ }
12
+ const sub = args[0];
13
+ const { value: profileFlag, rest } = extractFlag(args.slice(1), "profile");
14
+ try {
15
+ const client = await createAuthClient({ profileFlag });
16
+ switch (sub) {
17
+ case "list":
18
+ await orgList(client, rest);
19
+ return;
20
+ case "create":
21
+ await orgCreate(client, rest);
22
+ return;
23
+ case "get":
24
+ await orgGet(client, rest);
25
+ return;
26
+ case "update":
27
+ await orgUpdate(client, rest);
28
+ return;
29
+ default:
30
+ console.error(kleur.red(`Unknown org subcommand: ${sub ?? "(none)"}`));
31
+ console.log("Usage: seamless org <list|create|get|update|members>");
32
+ process.exit(1);
33
+ }
34
+ }
35
+ catch (err) {
36
+ reportAdminError(err);
37
+ }
38
+ }
39
+ async function runOrgMembers(args) {
40
+ const sub = args[0];
41
+ const { value: profileFlag, rest } = extractFlag(args.slice(1), "profile");
42
+ try {
43
+ const client = await createAuthClient({ profileFlag });
44
+ switch (sub) {
45
+ case "list":
46
+ await membersList(client, rest);
47
+ return;
48
+ case "add":
49
+ await membersAdd(client, rest);
50
+ return;
51
+ case "update":
52
+ await membersUpdate(client, rest);
53
+ return;
54
+ case "remove":
55
+ await membersRemove(client, rest);
56
+ return;
57
+ default:
58
+ console.error(kleur.red(`Unknown org members subcommand: ${sub ?? "(none)"}`));
59
+ console.log("Usage: seamless org members <list|add|update|remove>");
60
+ process.exit(1);
61
+ }
62
+ }
63
+ catch (err) {
64
+ reportAdminError(err);
65
+ }
66
+ }
67
+ async function orgList(client, rest) {
68
+ const json = rest.includes("--json");
69
+ const { organizations, total } = await listOrgs(client);
70
+ if (json) {
71
+ console.log(JSON.stringify(organizations, null, 2));
72
+ return;
73
+ }
74
+ if (organizations.length === 0) {
75
+ console.log(kleur.dim("No organizations."));
76
+ return;
77
+ }
78
+ for (const org of organizations) {
79
+ printOrgRow(org);
80
+ }
81
+ console.log(kleur.dim(`${total} organization${total === 1 ? "" : "s"}.`));
82
+ }
83
+ async function orgCreate(client, rest) {
84
+ const slugFlag = extractFlag(rest, "slug");
85
+ const nameFlag = extractFlag(slugFlag.rest, "name");
86
+ const name = nameFlag.value ?? nameFlag.rest.find((a) => !a.startsWith("--"));
87
+ if (!name) {
88
+ console.error(kleur.red("Usage: seamless org create <name> [--slug <slug>]"));
89
+ process.exit(1);
90
+ }
91
+ const body = { name };
92
+ if (slugFlag.value)
93
+ body.slug = slugFlag.value;
94
+ const org = await createOrg(client, body);
95
+ console.log(kleur.green(`Created organization ${str(org, "id") ?? ""}.`));
96
+ printOrg(org);
97
+ }
98
+ async function orgGet(client, rest) {
99
+ const json = rest.includes("--json");
100
+ const id = rest.find((a) => !a.startsWith("--"));
101
+ if (!id) {
102
+ console.error(kleur.red("Usage: seamless org get <id>"));
103
+ process.exit(1);
104
+ }
105
+ const org = await getOrg(client, id);
106
+ if (json) {
107
+ console.log(JSON.stringify(org, null, 2));
108
+ return;
109
+ }
110
+ printOrg(org);
111
+ }
112
+ async function orgUpdate(client, rest) {
113
+ const nameFlag = extractFlag(rest, "name");
114
+ const slugFlag = extractFlag(nameFlag.rest, "slug");
115
+ const id = slugFlag.rest.find((a) => !a.startsWith("--"));
116
+ if (!id) {
117
+ console.error(kleur.red("Usage: seamless org update <id> [--name <name>] [--slug <slug>]"));
118
+ process.exit(1);
119
+ }
120
+ const body = {};
121
+ if (nameFlag.value)
122
+ body.name = nameFlag.value;
123
+ if (slugFlag.value)
124
+ body.slug = slugFlag.value;
125
+ if (Object.keys(body).length === 0) {
126
+ console.error(kleur.red("Nothing to update. Pass --name and/or --slug."));
127
+ process.exit(1);
128
+ }
129
+ const org = await updateOrg(client, id, body);
130
+ console.log(kleur.green(`Updated organization ${id}.`));
131
+ printOrg(org);
132
+ }
133
+ async function membersList(client, rest) {
134
+ const json = rest.includes("--json");
135
+ const orgId = rest.find((a) => !a.startsWith("--"));
136
+ if (!orgId) {
137
+ console.error(kleur.red("Usage: seamless org members list <orgId>"));
138
+ process.exit(1);
139
+ }
140
+ const { members, total } = await listMembers(client, orgId);
141
+ if (json) {
142
+ console.log(JSON.stringify(members, null, 2));
143
+ return;
144
+ }
145
+ if (members.length === 0) {
146
+ console.log(kleur.dim("No members."));
147
+ return;
148
+ }
149
+ for (const member of members) {
150
+ printMemberRow(member);
151
+ }
152
+ console.log(kleur.dim(`${total} member${total === 1 ? "" : "s"}.`));
153
+ }
154
+ async function membersAdd(client, rest) {
155
+ const userFlag = extractFlag(rest, "user");
156
+ const emailFlag = extractFlag(userFlag.rest, "email");
157
+ const rolesFlag = extractFlag(emailFlag.rest, "roles");
158
+ const scopesFlag = extractFlag(rolesFlag.rest, "scopes");
159
+ const orgId = scopesFlag.rest.find((a) => !a.startsWith("--"));
160
+ if (!orgId || (!userFlag.value && !emailFlag.value)) {
161
+ console.error(kleur.red("Usage: seamless org members add <orgId> (--user <id> | --email <email>) [--roles a,b] [--scopes a,b]"));
162
+ process.exit(1);
163
+ }
164
+ const body = {};
165
+ if (userFlag.value)
166
+ body.userId = userFlag.value;
167
+ if (emailFlag.value)
168
+ body.email = emailFlag.value;
169
+ const roles = parseList(rolesFlag.value);
170
+ const scopes = parseList(scopesFlag.value);
171
+ if (roles)
172
+ body.roles = roles;
173
+ if (scopes)
174
+ body.scopes = scopes;
175
+ const membership = await addMember(client, orgId, body);
176
+ console.log(kleur.green("Added member."));
177
+ printMemberRow(membership);
178
+ }
179
+ async function membersUpdate(client, rest) {
180
+ const rolesFlag = extractFlag(rest, "roles");
181
+ const scopesFlag = extractFlag(rolesFlag.rest, "scopes");
182
+ const positional = scopesFlag.rest.filter((a) => !a.startsWith("--"));
183
+ const [orgId, userId] = positional;
184
+ if (!orgId || !userId) {
185
+ console.error(kleur.red("Usage: seamless org members update <orgId> <userId> [--roles a,b] [--scopes a,b]"));
186
+ process.exit(1);
187
+ }
188
+ const body = {};
189
+ const roles = parseList(rolesFlag.value);
190
+ const scopes = parseList(scopesFlag.value);
191
+ if (roles)
192
+ body.roles = roles;
193
+ if (scopes)
194
+ body.scopes = scopes;
195
+ if (Object.keys(body).length === 0) {
196
+ console.error(kleur.red("Nothing to update. Pass --roles and/or --scopes."));
197
+ process.exit(1);
198
+ }
199
+ const membership = await updateMember(client, orgId, userId, body);
200
+ console.log(kleur.green("Updated member."));
201
+ printMemberRow(membership);
202
+ }
203
+ async function membersRemove(client, rest) {
204
+ const positional = rest.filter((a) => !a.startsWith("--"));
205
+ const [orgId, userId] = positional;
206
+ if (!orgId || !userId) {
207
+ console.error(kleur.red("Usage: seamless org members remove <orgId> <userId>"));
208
+ process.exit(1);
209
+ }
210
+ const proceed = await confirm({
211
+ message: `Remove user ${userId} from organization ${orgId}?`,
212
+ initialValue: false,
213
+ });
214
+ if (isCancel(proceed) || !proceed) {
215
+ console.log("Cancelled.");
216
+ return;
217
+ }
218
+ await removeMember(client, orgId, userId);
219
+ console.log(kleur.green(`Removed user ${userId} from ${orgId}.`));
220
+ }
221
+ function printOrgRow(org) {
222
+ const id = str(org, "id") ?? "(no id)";
223
+ const name = str(org, "name") ?? "(no name)";
224
+ const slug = str(org, "slug");
225
+ console.log(kleur.bold(name) + kleur.dim(` ${id}`) + (slug ? kleur.dim(` (${slug})`) : ""));
226
+ }
227
+ function printOrg(org) {
228
+ const line = (label, value) => console.log(kleur.dim(`${label}:`.padEnd(8)) + value);
229
+ line("Id", str(org, "id") ?? "(unknown)");
230
+ line("Name", str(org, "name") ?? "(unknown)");
231
+ line("Slug", str(org, "slug") ?? "(none)");
232
+ }
233
+ function printMemberRow(member) {
234
+ const userId = str(member, "userId") ?? "(no user)";
235
+ const roles = Array.isArray(member.roles)
236
+ ? member.roles.filter((r) => typeof r === "string")
237
+ : [];
238
+ const scopes = Array.isArray(member.scopes)
239
+ ? member.scopes.filter((s) => typeof s === "string")
240
+ : [];
241
+ console.log(kleur.bold(userId) +
242
+ (roles.length ? kleur.dim(` roles: ${roles.join(", ")}`) : "") +
243
+ (scopes.length ? kleur.dim(` scopes: ${scopes.join(", ")}`) : ""));
244
+ }
245
+ function str(record, key) {
246
+ const value = record[key];
247
+ return typeof value === "string" && value ? value : undefined;
248
+ }
249
+ //# sourceMappingURL=org.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"org.js","sourceRoot":"","sources":["../../src/commands/org.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,150 @@
1
+ import { intro, outro, text, isCancel, cancel } from "@clack/prompts";
2
+ import kleur from "kleur";
3
+ import { extractFlag } from "../core/args.js";
4
+ import { DEFAULT_PROFILE_NAME, loadConfig, normalizeInstanceUrl, removeProfile, resolveActiveProfileName, setActiveProfile, upsertProfile, } from "../core/config.js";
5
+ import { deleteTokens, KeychainUnavailableError } from "../core/keychain.js";
6
+ export async function runProfile(args) {
7
+ const sub = args[0];
8
+ const rest = args.slice(1);
9
+ switch (sub) {
10
+ case "list":
11
+ profileList();
12
+ return;
13
+ case "add":
14
+ await profileAdd(rest);
15
+ return;
16
+ case "use":
17
+ profileUse(rest);
18
+ return;
19
+ case "remove":
20
+ await profileRemove(rest);
21
+ return;
22
+ default:
23
+ console.error(kleur.red(`Unknown profile subcommand: ${sub ?? "(none)"}`));
24
+ console.log("Usage: seamless profile <list|add|use|remove>");
25
+ process.exit(1);
26
+ }
27
+ }
28
+ function profileList() {
29
+ const config = loadConfig();
30
+ const active = resolveActiveProfileName({}, config);
31
+ const names = Object.keys(config.profiles);
32
+ if (names.length === 0) {
33
+ console.log(kleur.dim("No profiles yet. Add one with:"));
34
+ console.log(kleur.cyan(" seamless profile add <name> --instance-url <url>"));
35
+ return;
36
+ }
37
+ for (const name of names) {
38
+ const profile = config.profiles[name];
39
+ const marker = name === active ? kleur.green("* ") : " ";
40
+ const email = profile.email ? kleur.dim(` (${profile.email})`) : "";
41
+ console.log(marker + kleur.bold(name) + kleur.dim(` ${profile.instanceUrl}`) + email);
42
+ }
43
+ }
44
+ async function profileAdd(rest) {
45
+ const urlFlag = extractFlag(rest, "instance-url");
46
+ const typeFlag = extractFlag(urlFlag.rest, "identifier-type");
47
+ let name = typeFlag.rest[0];
48
+ let instanceUrl = urlFlag.value;
49
+ const identifierType = (typeFlag.value ?? "email");
50
+ if (identifierType !== "email" && identifierType !== "phone") {
51
+ console.error(kleur.red(`Invalid --identifier-type "${typeFlag.value}". Use email or phone.`));
52
+ process.exit(1);
53
+ }
54
+ intro("Add a Seamless profile");
55
+ if (!name) {
56
+ const answer = await text({
57
+ message: "Profile name",
58
+ placeholder: DEFAULT_PROFILE_NAME,
59
+ defaultValue: DEFAULT_PROFILE_NAME,
60
+ });
61
+ if (isCancel(answer)) {
62
+ cancel("Cancelled.");
63
+ return;
64
+ }
65
+ name = answer || DEFAULT_PROFILE_NAME;
66
+ }
67
+ if (!instanceUrl) {
68
+ const answer = await text({
69
+ message: "Instance URL",
70
+ placeholder: "https://auth.example.com",
71
+ validate: (value) => {
72
+ if (!value)
73
+ return "Instance URL is required";
74
+ try {
75
+ normalizeInstanceUrl(value);
76
+ }
77
+ catch (err) {
78
+ return err.message;
79
+ }
80
+ },
81
+ });
82
+ if (isCancel(answer)) {
83
+ cancel("Cancelled.");
84
+ return;
85
+ }
86
+ instanceUrl = answer;
87
+ }
88
+ let normalized;
89
+ try {
90
+ normalized = normalizeInstanceUrl(instanceUrl);
91
+ }
92
+ catch (err) {
93
+ outro(kleur.red(err.message));
94
+ process.exit(1);
95
+ }
96
+ const existing = loadConfig().profiles[name];
97
+ upsertProfile({
98
+ name,
99
+ instanceUrl: normalized,
100
+ identifierType,
101
+ sub: existing?.sub,
102
+ email: existing?.email,
103
+ });
104
+ outro(kleur.green(`Profile "${name}" saved (${normalized})`));
105
+ }
106
+ function profileUse(rest) {
107
+ const name = rest[0];
108
+ if (!name) {
109
+ console.error(kleur.red("Usage: seamless profile use <name>"));
110
+ process.exit(1);
111
+ }
112
+ try {
113
+ setActiveProfile(name);
114
+ }
115
+ catch (err) {
116
+ console.error(kleur.red(err.message));
117
+ process.exit(1);
118
+ }
119
+ console.log(kleur.green(`Active profile set to "${name}".`));
120
+ }
121
+ async function profileRemove(rest) {
122
+ const name = rest[0];
123
+ if (!name) {
124
+ console.error(kleur.red("Usage: seamless profile remove <name>"));
125
+ process.exit(1);
126
+ }
127
+ const profile = loadConfig().profiles[name];
128
+ try {
129
+ removeProfile(name);
130
+ }
131
+ catch (err) {
132
+ console.error(kleur.red(err.message));
133
+ process.exit(1);
134
+ }
135
+ if (profile) {
136
+ try {
137
+ await deleteTokens(profile);
138
+ }
139
+ catch (err) {
140
+ if (err instanceof KeychainUnavailableError) {
141
+ console.log(kleur.dim("No keychain available; no stored tokens to clear."));
142
+ }
143
+ else {
144
+ console.log(kleur.yellow(`Could not clear stored tokens: ${err.message}`));
145
+ }
146
+ }
147
+ }
148
+ console.log(kleur.green(`Profile "${name}" removed.`));
149
+ }
150
+ //# 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,112 @@
1
+ import { confirm, isCancel } from "@clack/prompts";
2
+ import kleur from "kleur";
3
+ import { extractFlag } from "../core/args.js";
4
+ import { createAuthClient, ReauthRequiredError } from "../core/authClient.js";
5
+ import { clearLocalSession } from "../core/session.js";
6
+ import { listSessions, revokeAllSessions, revokeSessionById, } from "../core/sessions.js";
7
+ export async function runSessions(args) {
8
+ const sub = args[0] === "list" || args[0] === "revoke" ? args[0] : undefined;
9
+ const rest = sub ? args.slice(1) : args;
10
+ const { value: profileFlag, rest: positional } = extractFlag(rest, "profile");
11
+ try {
12
+ const client = await createAuthClient({ profileFlag });
13
+ if (sub === "revoke") {
14
+ await revoke(client, positional);
15
+ }
16
+ else {
17
+ await list(client);
18
+ }
19
+ }
20
+ catch (err) {
21
+ if (err instanceof ReauthRequiredError) {
22
+ console.log(kleur.yellow(err.message));
23
+ process.exit(1);
24
+ }
25
+ console.error(kleur.red(err.message));
26
+ process.exit(1);
27
+ }
28
+ }
29
+ async function list(client) {
30
+ const sessions = await listSessions(client);
31
+ if (sessions.length === 0) {
32
+ console.log(kleur.dim("No active sessions."));
33
+ return;
34
+ }
35
+ for (const session of sessions) {
36
+ printSession(session);
37
+ }
38
+ }
39
+ async function revoke(client, positional) {
40
+ const all = positional.includes("--all");
41
+ const id = positional.find((arg) => !arg.startsWith("--"));
42
+ if (all) {
43
+ const proceed = await confirm({
44
+ message: "Revoke every session, including this one? You will be signed out here.",
45
+ initialValue: false,
46
+ });
47
+ if (isCancel(proceed) || !proceed) {
48
+ console.log("Cancelled.");
49
+ return;
50
+ }
51
+ const res = await revokeAllSessions(client);
52
+ if (!res.ok) {
53
+ console.error(kleur.red(`Could not revoke sessions (${res.status}).`));
54
+ process.exit(1);
55
+ }
56
+ await clearLocalSession(client.profile);
57
+ console.log(kleur.green("Revoked all sessions."));
58
+ console.log(kleur.dim("Local tokens cleared. Run seamless login to sign in again."));
59
+ return;
60
+ }
61
+ if (!id) {
62
+ console.error(kleur.red("Usage: seamless sessions revoke <id> | seamless sessions revoke --all"));
63
+ process.exit(1);
64
+ }
65
+ const sessions = await listSessions(client);
66
+ const isCurrent = sessions.find((session) => session.id === id)?.current ?? false;
67
+ if (isCurrent) {
68
+ const proceed = await confirm({
69
+ message: "This is your current session. Revoking it signs you out here. Continue?",
70
+ initialValue: false,
71
+ });
72
+ if (isCancel(proceed) || !proceed) {
73
+ console.log("Cancelled.");
74
+ return;
75
+ }
76
+ }
77
+ const res = await revokeSessionById(client, id);
78
+ if (res.status === 404) {
79
+ console.log(kleur.yellow(`No active session ${id}. It may already be revoked.`));
80
+ return;
81
+ }
82
+ if (!res.ok) {
83
+ console.error(kleur.red(`Could not revoke session ${id} (${res.status}).`));
84
+ process.exit(1);
85
+ }
86
+ console.log(kleur.green(`Revoked session ${id}.`));
87
+ if (isCurrent) {
88
+ await clearLocalSession(client.profile);
89
+ console.log(kleur.dim("That was your current session; local tokens cleared. Run seamless login to sign in again."));
90
+ }
91
+ }
92
+ function printSession(session) {
93
+ const marker = session.current ? kleur.green("* ") : " ";
94
+ const device = session.deviceName ?? shortUserAgent(session.userAgent) ?? "unknown device";
95
+ const ip = session.ipAddress ?? "unknown ip";
96
+ const when = session.lastUsedAt ? formatWhen(session.lastUsedAt) : "unknown";
97
+ console.log(marker + kleur.bold(session.id));
98
+ console.log(` ${device} ${kleur.dim(ip)}`);
99
+ console.log(kleur.dim(` last used ${when}${session.current ? " (current)" : ""}`));
100
+ }
101
+ function shortUserAgent(userAgent) {
102
+ if (!userAgent)
103
+ return undefined;
104
+ return userAgent.length > 48 ? `${userAgent.slice(0, 45)}...` : userAgent;
105
+ }
106
+ function formatWhen(iso) {
107
+ const date = new Date(iso);
108
+ if (Number.isNaN(date.getTime()))
109
+ return iso;
110
+ return `${date.toISOString().slice(0, 16).replace("T", " ")} UTC`;
111
+ }
112
+ //# sourceMappingURL=sessions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sessions.js","sourceRoot":"","sources":["../../src/commands/sessions.ts"],"names":[],"mappings":"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"}