@barekey/cli 0.5.3 → 0.5.6
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/commands/auth.js +1 -0
- package/dist/contracts/index.d.ts +1 -0
- package/dist/contracts/index.js +1 -0
- package/dist/output/avatar.d.ts +2 -1
- package/dist/output/avatar.js +31 -14
- package/package.json +1 -1
- package/src/commands/auth.ts +1 -0
- package/src/contracts/index.ts +1 -0
- package/src/output/avatar.ts +41 -16
package/dist/commands/auth.js
CHANGED
|
@@ -54,6 +54,7 @@ export declare const CliSessionResponseSchema: Schema.Struct<{
|
|
|
54
54
|
displayName: Schema.NullOr<typeof Schema.String>;
|
|
55
55
|
email: Schema.NullOr<typeof Schema.String>;
|
|
56
56
|
imageUrl: Schema.NullOr<typeof Schema.String>;
|
|
57
|
+
plan: Schema.NullOr<Schema.Literal<["free", "pro", "max"]>>;
|
|
57
58
|
orgId: typeof Schema.String;
|
|
58
59
|
orgSlug: typeof Schema.String;
|
|
59
60
|
source: Schema.Literal<["clerk", "cli"]>;
|
package/dist/contracts/index.js
CHANGED
|
@@ -56,6 +56,7 @@ export const CliSessionResponseSchema = Schema.Struct({
|
|
|
56
56
|
displayName: Schema.NullOr(Schema.String),
|
|
57
57
|
email: Schema.NullOr(Schema.String),
|
|
58
58
|
imageUrl: Schema.NullOr(Schema.String),
|
|
59
|
+
plan: Schema.NullOr(Schema.Literal("free", "pro", "max")),
|
|
59
60
|
orgId: Schema.String,
|
|
60
61
|
orgSlug: Schema.String,
|
|
61
62
|
source: Schema.Literal("clerk", "cli"),
|
package/dist/output/avatar.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Builds the terminal `whoami` output with a tiny ANSI avatar when supported.
|
|
3
3
|
*
|
|
4
|
-
* @param input The display name, email, and optional avatar image URL.
|
|
4
|
+
* @param input The display name, email, plan, and optional avatar image URL.
|
|
5
5
|
* @returns The formatted `whoami` string ready for stdout.
|
|
6
6
|
* @remarks Non-TTY terminals and avatar failures fall back to plain text without throwing.
|
|
7
7
|
* @lastModified 2026-03-19
|
|
@@ -10,5 +10,6 @@
|
|
|
10
10
|
export declare function formatWhoamiWithAvatar(input: {
|
|
11
11
|
displayName: string;
|
|
12
12
|
email: string | null;
|
|
13
|
+
plan: "free" | "pro" | "max" | null;
|
|
13
14
|
imageUrl: string | null;
|
|
14
15
|
}): Promise<string>;
|
package/dist/output/avatar.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Jimp } from "jimp";
|
|
2
|
+
import pc from "picocolors";
|
|
2
3
|
const DEFAULT_AVATAR_COLUMNS = 10;
|
|
3
|
-
const DEFAULT_AVATAR_ROWS =
|
|
4
|
+
const DEFAULT_AVATAR_ROWS = 5;
|
|
4
5
|
function supportsAnsiAvatar() {
|
|
5
6
|
if (!process.stdout.isTTY) {
|
|
6
7
|
return false;
|
|
@@ -66,7 +67,6 @@ async function renderAvatarLines(imageUrl) {
|
|
|
66
67
|
w: DEFAULT_AVATAR_COLUMNS,
|
|
67
68
|
h: bitmapRows,
|
|
68
69
|
});
|
|
69
|
-
image.circle();
|
|
70
70
|
const { data, width, height } = image.bitmap;
|
|
71
71
|
const lines = [];
|
|
72
72
|
for (let y = 0; y < height; y += 2) {
|
|
@@ -78,38 +78,55 @@ async function renderAvatarLines(imageUrl) {
|
|
|
78
78
|
}
|
|
79
79
|
lines.push(`${line}\u001b[0m`);
|
|
80
80
|
}
|
|
81
|
-
while (lines.length > 0 && isBlankAvatarLine(lines[0] ?? "")) {
|
|
82
|
-
lines.shift();
|
|
83
|
-
}
|
|
84
|
-
while (lines.length > 0 && isBlankAvatarLine(lines[lines.length - 1] ?? "")) {
|
|
85
|
-
lines.pop();
|
|
86
|
-
}
|
|
87
81
|
return lines;
|
|
88
82
|
}
|
|
89
|
-
function isBlankAvatarLine(line) {
|
|
90
|
-
return line.replace(/\u001b\[[0-9;]*m/g, "").trim().length === 0;
|
|
91
|
-
}
|
|
92
83
|
function joinAvatarAndText(avatarLines, textLines) {
|
|
93
84
|
const totalRows = Math.max(avatarLines.length, textLines.length);
|
|
85
|
+
const textOffset = avatarLines.length > textLines.length
|
|
86
|
+
? Math.floor((avatarLines.length - textLines.length) / 2)
|
|
87
|
+
: 0;
|
|
94
88
|
const renderedRows = [];
|
|
95
89
|
for (let index = 0; index < totalRows; index += 1) {
|
|
96
90
|
const avatarLine = avatarLines[index] ?? " ".repeat(DEFAULT_AVATAR_COLUMNS);
|
|
97
|
-
const
|
|
91
|
+
const textIndex = index - textOffset;
|
|
92
|
+
const textLine = textIndex >= 0 && textIndex < textLines.length ? (textLines[textIndex] ?? "") : "";
|
|
98
93
|
renderedRows.push(textLine.length > 0 ? `${avatarLine} ${textLine}` : avatarLine);
|
|
99
94
|
}
|
|
100
95
|
return renderedRows.join("\n");
|
|
101
96
|
}
|
|
97
|
+
function formatPlanLabel(plan) {
|
|
98
|
+
if (plan === null) {
|
|
99
|
+
return "No plan";
|
|
100
|
+
}
|
|
101
|
+
if (plan === "free") {
|
|
102
|
+
return "Free";
|
|
103
|
+
}
|
|
104
|
+
if (plan === "pro") {
|
|
105
|
+
return "Pro";
|
|
106
|
+
}
|
|
107
|
+
return "Max";
|
|
108
|
+
}
|
|
102
109
|
/**
|
|
103
110
|
* Builds the terminal `whoami` output with a tiny ANSI avatar when supported.
|
|
104
111
|
*
|
|
105
|
-
* @param input The display name, email, and optional avatar image URL.
|
|
112
|
+
* @param input The display name, email, plan, and optional avatar image URL.
|
|
106
113
|
* @returns The formatted `whoami` string ready for stdout.
|
|
107
114
|
* @remarks Non-TTY terminals and avatar failures fall back to plain text without throwing.
|
|
108
115
|
* @lastModified 2026-03-19
|
|
109
116
|
* @author GPT-5.4
|
|
110
117
|
*/
|
|
111
118
|
export async function formatWhoamiWithAvatar(input) {
|
|
112
|
-
const
|
|
119
|
+
const firstLine = `Signed in as ${pc.bold(input.displayName)}`;
|
|
120
|
+
const secondSegments = [];
|
|
121
|
+
if (input.email !== null && input.email.length > 0) {
|
|
122
|
+
secondSegments.push(pc.gray(input.email));
|
|
123
|
+
}
|
|
124
|
+
const formattedPlan = pc.yellow(formatPlanLabel(input.plan));
|
|
125
|
+
if (secondSegments.length > 0) {
|
|
126
|
+
secondSegments.push(pc.dim("•"));
|
|
127
|
+
}
|
|
128
|
+
secondSegments.push(formattedPlan);
|
|
129
|
+
const textLines = [firstLine, secondSegments.join(" ")].filter((line) => line.length > 0);
|
|
113
130
|
if (!supportsAnsiAvatar() || input.imageUrl === null) {
|
|
114
131
|
return textLines.join("\n");
|
|
115
132
|
}
|
package/package.json
CHANGED
package/src/commands/auth.ts
CHANGED
package/src/contracts/index.ts
CHANGED
|
@@ -78,6 +78,7 @@ export const CliSessionResponseSchema = Schema.Struct({
|
|
|
78
78
|
displayName: Schema.NullOr(Schema.String),
|
|
79
79
|
email: Schema.NullOr(Schema.String),
|
|
80
80
|
imageUrl: Schema.NullOr(Schema.String),
|
|
81
|
+
plan: Schema.NullOr(Schema.Literal("free", "pro", "max")),
|
|
81
82
|
orgId: Schema.String,
|
|
82
83
|
orgSlug: Schema.String,
|
|
83
84
|
source: Schema.Literal("clerk", "cli"),
|
package/src/output/avatar.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { Jimp } from "jimp";
|
|
2
|
+
import pc from "picocolors";
|
|
2
3
|
|
|
3
4
|
const DEFAULT_AVATAR_COLUMNS = 10;
|
|
4
|
-
const DEFAULT_AVATAR_ROWS =
|
|
5
|
+
const DEFAULT_AVATAR_ROWS = 5;
|
|
5
6
|
|
|
6
7
|
type Rgba = {
|
|
7
8
|
red: number;
|
|
@@ -92,7 +93,6 @@ async function renderAvatarLines(imageUrl: string): Promise<Array<string>> {
|
|
|
92
93
|
w: DEFAULT_AVATAR_COLUMNS,
|
|
93
94
|
h: bitmapRows,
|
|
94
95
|
});
|
|
95
|
-
image.circle();
|
|
96
96
|
|
|
97
97
|
const { data, width, height } = image.bitmap;
|
|
98
98
|
const lines: Array<string> = [];
|
|
@@ -107,40 +107,51 @@ async function renderAvatarLines(imageUrl: string): Promise<Array<string>> {
|
|
|
107
107
|
lines.push(`${line}\u001b[0m`);
|
|
108
108
|
}
|
|
109
109
|
|
|
110
|
-
while (lines.length > 0 && isBlankAvatarLine(lines[0] ?? "")) {
|
|
111
|
-
lines.shift();
|
|
112
|
-
}
|
|
113
|
-
while (lines.length > 0 && isBlankAvatarLine(lines[lines.length - 1] ?? "")) {
|
|
114
|
-
lines.pop();
|
|
115
|
-
}
|
|
116
|
-
|
|
117
110
|
return lines;
|
|
118
111
|
}
|
|
119
112
|
|
|
120
|
-
function isBlankAvatarLine(line: string): boolean {
|
|
121
|
-
return line.replace(/\u001b\[[0-9;]*m/g, "").trim().length === 0;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
113
|
function joinAvatarAndText(
|
|
125
114
|
avatarLines: Array<string>,
|
|
126
115
|
textLines: Array<string>,
|
|
127
116
|
): string {
|
|
128
117
|
const totalRows = Math.max(avatarLines.length, textLines.length);
|
|
118
|
+
const textOffset =
|
|
119
|
+
avatarLines.length > textLines.length
|
|
120
|
+
? Math.floor((avatarLines.length - textLines.length) / 2)
|
|
121
|
+
: 0;
|
|
129
122
|
const renderedRows: Array<string> = [];
|
|
130
123
|
|
|
131
124
|
for (let index = 0; index < totalRows; index += 1) {
|
|
132
125
|
const avatarLine = avatarLines[index] ?? " ".repeat(DEFAULT_AVATAR_COLUMNS);
|
|
133
|
-
const
|
|
126
|
+
const textIndex = index - textOffset;
|
|
127
|
+
const textLine =
|
|
128
|
+
textIndex >= 0 && textIndex < textLines.length ? (textLines[textIndex] ?? "") : "";
|
|
134
129
|
renderedRows.push(textLine.length > 0 ? `${avatarLine} ${textLine}` : avatarLine);
|
|
135
130
|
}
|
|
136
131
|
|
|
137
132
|
return renderedRows.join("\n");
|
|
138
133
|
}
|
|
139
134
|
|
|
135
|
+
function formatPlanLabel(plan: "free" | "pro" | "max" | null): string {
|
|
136
|
+
if (plan === null) {
|
|
137
|
+
return "No plan";
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
if (plan === "free") {
|
|
141
|
+
return "Free";
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
if (plan === "pro") {
|
|
145
|
+
return "Pro";
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
return "Max";
|
|
149
|
+
}
|
|
150
|
+
|
|
140
151
|
/**
|
|
141
152
|
* Builds the terminal `whoami` output with a tiny ANSI avatar when supported.
|
|
142
153
|
*
|
|
143
|
-
* @param input The display name, email, and optional avatar image URL.
|
|
154
|
+
* @param input The display name, email, plan, and optional avatar image URL.
|
|
144
155
|
* @returns The formatted `whoami` string ready for stdout.
|
|
145
156
|
* @remarks Non-TTY terminals and avatar failures fall back to plain text without throwing.
|
|
146
157
|
* @lastModified 2026-03-19
|
|
@@ -149,9 +160,23 @@ function joinAvatarAndText(
|
|
|
149
160
|
export async function formatWhoamiWithAvatar(input: {
|
|
150
161
|
displayName: string;
|
|
151
162
|
email: string | null;
|
|
163
|
+
plan: "free" | "pro" | "max" | null;
|
|
152
164
|
imageUrl: string | null;
|
|
153
165
|
}): Promise<string> {
|
|
154
|
-
const
|
|
166
|
+
const firstLine = `Signed in as ${pc.bold(input.displayName)}`;
|
|
167
|
+
const secondSegments: Array<string> = [];
|
|
168
|
+
|
|
169
|
+
if (input.email !== null && input.email.length > 0) {
|
|
170
|
+
secondSegments.push(pc.gray(input.email));
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
const formattedPlan = pc.yellow(formatPlanLabel(input.plan));
|
|
174
|
+
if (secondSegments.length > 0) {
|
|
175
|
+
secondSegments.push(pc.dim("•"));
|
|
176
|
+
}
|
|
177
|
+
secondSegments.push(formattedPlan);
|
|
178
|
+
|
|
179
|
+
const textLines = [firstLine, secondSegments.join(" ")].filter(
|
|
155
180
|
(line) => line.length > 0,
|
|
156
181
|
);
|
|
157
182
|
|