jobless 1.0.0 → 1.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.
- package/README.md +40 -30
- package/package.json +7 -4
- package/src/data.js +20 -15
- package/src/screens.js +11 -10
package/README.md
CHANGED
|
@@ -1,56 +1,66 @@
|
|
|
1
1
|
# jobless
|
|
2
2
|
|
|
3
|
-
A terminal resume for a broken job market.
|
|
4
|
-
|
|
5
|
-
LinkedIn turned into social media. Applications take 30 minutes and get rejected by a bot. Recruiters schedule interviews, then vanish. This package is the profile I actually want people to read.
|
|
6
|
-
|
|
7
3
|
```bash
|
|
8
4
|
npx jobless
|
|
9
5
|
```
|
|
10
6
|
|
|
11
|
-
|
|
7
|
+
A terminal resume for a broken job market. LinkedIn is a content farm with a jobs tab. Applications take 30 minutes. The no takes 400ms. Recruiters book the call so they have something to cancel. I still do not know their coffee, their mug, or their star sign.
|
|
8
|
+
|
|
9
|
+
## The market
|
|
10
|
+
|
|
11
|
+
### I do not know their coffee, their mug, or their stars
|
|
12
|
+
|
|
13
|
+
The job posting said TypeScript, PostgreSQL, and "excellent communication." The actual exam is telepathy. What is on the recruiter's mind at 10:02am. Oat milk or "just black, I ship." What color is the mug. Company merch that says world-class talent, or the chipped navy one from a 2019 conference that still has a lipstick ghost. What is their star sign. A Virgo who will reject you for a missing Oxford comma. A Gemini who double-booked you with someone named also-Yonas. A Scorpio who already decided during the handshake.
|
|
14
|
+
|
|
15
|
+
I can trace a silent cron death across 17 processes. I cannot see into their mug. Apparently that was the seniority gap. Next round I will bring a natal chart, a color swatch, and a cortado. Or we could talk about the actual system.
|
|
16
|
+
|
|
17
|
+
### I applied for 30 minutes. The bot needed 400ms
|
|
18
|
+
|
|
19
|
+
The modern application is unpaid data entry with extra steps. Upload the PDF. Then type the PDF into twelve boxes the parser already filled wrong. Then salary in USD, GBP, and emotional damage. Then a culture quiz written by someone who has never been in the culture. Then "why this company?" as if Greenhouse is going to light a candle and read it.
|
|
20
|
+
|
|
21
|
+
Submit. Rejected in 400ms. Sometimes the no arrives before the confirmation. Five years in production, $100K pulled out of infra, payment rails that moved billions — filtered out because I did not write "synergy" enough times. Cool product. Would not ship it.
|
|
22
|
+
|
|
23
|
+
### They booked the call so they had something to cancel
|
|
24
|
+
|
|
25
|
+
Favorite genre of fiction: the recruiter calendar invite. "Loved your profile. Thursday 10am?" I clear the morning. I make tea. I put on a shirt with buttons. 9:58am: "we've decided to move forward with other candidates." Which other candidates. The ones you have not scheduled yet?
|
|
26
|
+
|
|
27
|
+
If ghosting is the process, skip the theater. I debug silent failures for a living. Yours is not that silent.
|
|
28
|
+
|
|
29
|
+
### LinkedIn: 40% more thought leadership, 0% more jobs
|
|
30
|
+
|
|
31
|
+
LinkedIn used to be a jobs board that accidentally had a feed. Now it is a feed that accidentally has jobs. Everyone is humbled. Everyone is announcing. Everyone is a thought leader on a Tuesday. The algorithm loves a carousel called "10 habits of senior engineers" from someone who has never been on-call. It does not love the person who actually kept production up.
|
|
32
|
+
|
|
33
|
+
I did not open this app to like your new chapter. I opened it because I can build the thing you are posting about.
|
|
12
34
|
|
|
13
35
|
```bash
|
|
14
|
-
npx jobless
|
|
15
|
-
npx jobless who # who I am
|
|
16
|
-
npx jobless looking # roles I want
|
|
17
|
-
npx jobless rant # the market, unfiltered
|
|
18
|
-
npx jobless work # proof of work
|
|
19
|
-
npx jobless skills # the stack
|
|
20
|
-
npx jobless hire # links + email
|
|
21
|
-
npx jobless --json # machine readable
|
|
22
|
-
npx jobless --no-anim # skip the ATS joke
|
|
36
|
+
npx jobless rant
|
|
23
37
|
```
|
|
24
38
|
|
|
25
39
|
## Yonas Alem
|
|
26
40
|
|
|
27
41
|
Senior Software Engineer in Addis Ababa. Open to remote senior roles.
|
|
28
42
|
|
|
43
|
+
5+ years in production · 35% infra cost cut · ~30% performance gain · 3B+ ETB payment volume
|
|
44
|
+
|
|
29
45
|
- Site: [yonasalem.vercel.app](https://yonasalem.vercel.app)
|
|
30
46
|
- GitHub: [github.com/Yonas21](https://github.com/Yonas21)
|
|
31
47
|
- LinkedIn: [linkedin.com/in/yonasalem21](https://www.linkedin.com/in/yonasalem21/)
|
|
32
48
|
- Email: yonalem21@gmail.com
|
|
33
49
|
|
|
34
|
-
Zero dependencies. Node 18+.
|
|
35
|
-
|
|
36
|
-
## Publish
|
|
37
|
-
|
|
38
|
-
npm now requires 2FA or a granular token. Browser login alone is not enough.
|
|
39
|
-
|
|
40
|
-
1. Enable 2FA on your npm account: [npmjs.com/settings](https://www.npmjs.com/) → Account → Two-Factor Authentication.
|
|
41
|
-
2. Publish with the authenticator code:
|
|
42
|
-
|
|
43
50
|
```bash
|
|
44
|
-
|
|
51
|
+
npx jobless hire
|
|
45
52
|
```
|
|
46
53
|
|
|
47
|
-
|
|
54
|
+
## Commands
|
|
48
55
|
|
|
49
56
|
```bash
|
|
50
|
-
|
|
51
|
-
|
|
57
|
+
npx jobless # interactive
|
|
58
|
+
npx jobless rant # the market, with jokes
|
|
59
|
+
npx jobless who # who I am
|
|
60
|
+
npx jobless looking # roles I want
|
|
61
|
+
npx jobless work # proof of work
|
|
62
|
+
npx jobless skills # the stack
|
|
63
|
+
npx jobless hire # links + email
|
|
52
64
|
```
|
|
53
65
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
> I was so done with the job market that I published a resume to npm. Run `npx jobless`.
|
|
66
|
+
Zero dependencies. Node 18+.
|
package/package.json
CHANGED
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jobless",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "A terminal resume for a broken job market.
|
|
3
|
+
"version": "1.1.0",
|
|
4
|
+
"description": "npx jobless — I still do not know the recruiter's coffee, mug color, or star sign. A terminal resume for a broken job market.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cli",
|
|
7
7
|
"npx",
|
|
8
8
|
"resume",
|
|
9
|
-
"
|
|
9
|
+
"rant",
|
|
10
|
+
"job-market",
|
|
11
|
+
"linkedin",
|
|
12
|
+
"recruiter",
|
|
10
13
|
"terminal",
|
|
11
|
-
"
|
|
14
|
+
"portfolio",
|
|
12
15
|
"yonas-alem"
|
|
13
16
|
],
|
|
14
17
|
"license": "MIT",
|
package/src/data.js
CHANGED
|
@@ -41,24 +41,29 @@ export const lookingFor = {
|
|
|
41
41
|
'Managers who can say no to a 7-round interview for a role they already understand.',
|
|
42
42
|
],
|
|
43
43
|
no: [
|
|
44
|
-
'
|
|
45
|
-
'"Entry-level"
|
|
46
|
-
'Culture surveys
|
|
44
|
+
'Take-homes that are just your Q3 roadmap with a Sunday deadline.',
|
|
45
|
+
'"Entry-level." Must have 5 years, 12 frameworks, and a personal brand.',
|
|
46
|
+
'Culture surveys longer than the product spec.',
|
|
47
|
+
'Interviews that secretly grade my guess at their coffee order.',
|
|
47
48
|
],
|
|
48
49
|
};
|
|
49
50
|
|
|
50
51
|
export const rants = [
|
|
51
52
|
{
|
|
52
|
-
title: 'LinkedIn
|
|
53
|
-
body: "LinkedIn used to be
|
|
53
|
+
title: 'LinkedIn: 40% more thought leadership, 0% more jobs',
|
|
54
|
+
body: "LinkedIn used to be a jobs board that accidentally had a feed. Now it is a feed that accidentally has jobs. Everyone is humbled. Everyone is announcing. Everyone is a thought leader on a Tuesday. The algorithm loves a carousel called '10 habits of senior engineers' from someone who has never been on-call. It does not love the person who actually kept production up. I did not open this app to like your new chapter. I opened it because I can build the thing you are posting about.",
|
|
54
55
|
},
|
|
55
56
|
{
|
|
56
|
-
title: '
|
|
57
|
-
body: '
|
|
57
|
+
title: 'I applied for 30 minutes. The bot needed 400ms',
|
|
58
|
+
body: 'The modern application is unpaid data entry with extra steps. Upload the PDF. Then type the PDF into twelve boxes the parser already filled wrong. Then salary in USD, GBP, and emotional damage. Then a culture quiz written by someone who has never been in the culture. Then "why this company?" as if Greenhouse is going to light a candle and read it. Submit. Rejected in 400ms. Sometimes the no arrives before the confirmation. Five years in production, $100K pulled out of infra, payment rails that moved billions — filtered out because I did not write "synergy" enough times. Cool product. Would not ship it.',
|
|
58
59
|
},
|
|
59
60
|
{
|
|
60
|
-
title: '
|
|
61
|
-
body: '
|
|
61
|
+
title: 'They booked the call so they had something to cancel',
|
|
62
|
+
body: 'Favorite genre of fiction: the recruiter calendar invite. "Loved your profile. Thursday 10am?" I clear the morning. I make tea. I put on a shirt with buttons. 9:58am: "we\'ve decided to move forward with other candidates." Which other candidates. The ones you have not scheduled yet? Or they just never show, and the Google Calendar event is the last proof a human existed. If ghosting is the process, skip the theater. Do not put a working engineer on your Greenhouse stage so the pipeline looks busy. I debug silent failures for a living. Yours is not that silent.',
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
title: 'I do not know their coffee, their mug, or their stars',
|
|
66
|
+
body: "The job posting said TypeScript, PostgreSQL, and 'excellent communication.' The actual exam is telepathy. What is on the recruiter's mind at 10:02am. Oat milk or 'just black, I ship.' What color is the mug. Company merch that says world-class talent, or the chipped navy one from a 2019 conference that still has a lipstick ghost. What is their star sign. A Virgo who will reject you for a missing Oxford comma. A Gemini who double-booked you with someone named also-Yonas. A Scorpio who already decided during the handshake. I can trace a silent cron death across 17 processes. I cannot see into their mug. Apparently that was the seniority gap. Next round I will bring a natal chart, a color swatch, and a cortado. Or we could talk about the actual system.",
|
|
62
67
|
},
|
|
63
68
|
];
|
|
64
69
|
|
|
@@ -166,7 +171,7 @@ export const quotes = [
|
|
|
166
171
|
export const menu = [
|
|
167
172
|
{ key: '1', command: 'who', label: 'who I am' },
|
|
168
173
|
{ key: '2', command: 'looking', label: 'roles I want' },
|
|
169
|
-
{ key: '3', command: 'rant', label: 'the market,
|
|
174
|
+
{ key: '3', command: 'rant', label: 'the market, with jokes' },
|
|
170
175
|
{ key: '4', command: 'work', label: 'proof of work' },
|
|
171
176
|
{ key: '5', command: 'skills', label: 'the stack' },
|
|
172
177
|
{ key: '6', command: 'hire', label: 'hire me / links' },
|
|
@@ -174,9 +179,9 @@ export const menu = [
|
|
|
174
179
|
];
|
|
175
180
|
|
|
176
181
|
export const bootLines = [
|
|
177
|
-
'
|
|
178
|
-
'
|
|
179
|
-
'
|
|
180
|
-
'
|
|
181
|
-
'human
|
|
182
|
+
'uploading resume.pdf',
|
|
183
|
+
'guessing oat milk vs just-black-I-ship',
|
|
184
|
+
'guessing navy mug vs emotional-support Stanley',
|
|
185
|
+
'checking if Mercury is in Greenhouse',
|
|
186
|
+
'404 human',
|
|
182
187
|
];
|
package/src/screens.js
CHANGED
|
@@ -74,7 +74,7 @@ export const printHeader = () => {
|
|
|
74
74
|
export const printBoot = async () => {
|
|
75
75
|
hideCursor();
|
|
76
76
|
try {
|
|
77
|
-
print(dim('
|
|
77
|
+
print(dim(' applying to a role that was closed in 2022...'));
|
|
78
78
|
blank();
|
|
79
79
|
for (const [index, line] of bootLines.entries()) {
|
|
80
80
|
print(` ${dim(`[${String(index + 1)}/5]`)} ${line}`);
|
|
@@ -82,9 +82,9 @@ export const printBoot = async () => {
|
|
|
82
82
|
}
|
|
83
83
|
blank();
|
|
84
84
|
print(` ${bold(red('RESULT'))} ${bold('REJECTED')}`);
|
|
85
|
-
print(` ${dim('reason')}
|
|
86
|
-
print(` ${dim('elapsed')} 0.
|
|
87
|
-
print(` ${dim('note')}
|
|
85
|
+
print(` ${dim('reason')} guessed white mug. it was navy. also a Virgo.`);
|
|
86
|
+
print(` ${dim('elapsed')} 0.40s (personal best)`);
|
|
87
|
+
print(` ${dim('note')} the loading bar is the joke. the rejection is documentary.`);
|
|
88
88
|
} finally {
|
|
89
89
|
showCursor();
|
|
90
90
|
}
|
|
@@ -125,7 +125,7 @@ export const printRant = () => {
|
|
|
125
125
|
section('THE MARKET');
|
|
126
126
|
blank();
|
|
127
127
|
for (const line of wrap(
|
|
128
|
-
'
|
|
128
|
+
'The feed is thriving. Hiring is a lore page. The recruiter\'s coffee order is a senior requirement.',
|
|
129
129
|
)) {
|
|
130
130
|
print(` ${dim(line)}`);
|
|
131
131
|
}
|
|
@@ -134,7 +134,7 @@ export const printRant = () => {
|
|
|
134
134
|
print(box([bold(yellow(rant.title)), '', ...wrap(rant.body, inner())]));
|
|
135
135
|
}
|
|
136
136
|
blank();
|
|
137
|
-
print(` ${dim('
|
|
137
|
+
print(` ${dim('Still here? Congrats. You already outperformed the ATS.')}`);
|
|
138
138
|
};
|
|
139
139
|
|
|
140
140
|
export const printWork = () => {
|
|
@@ -220,15 +220,16 @@ export const printHelp = () => {
|
|
|
220
220
|
print(` ${bold('npx jobless --json')} machine readable`);
|
|
221
221
|
print(` ${bold('npx jobless --no-anim')} skip the ATS joke`);
|
|
222
222
|
blank();
|
|
223
|
-
print(` ${dim('Built because
|
|
223
|
+
print(` ${dim('Built because the feed would not shut up.')}`);
|
|
224
224
|
print(` ${dim(profile.website)}`);
|
|
225
225
|
};
|
|
226
226
|
|
|
227
227
|
export const printLandingTeaser = () => {
|
|
228
228
|
blank();
|
|
229
|
-
print(` ${yellow('LinkedIn is a
|
|
230
|
-
print(` ${dim('Applications take 30 minutes.
|
|
231
|
-
print(` ${dim('Recruiters book the call
|
|
229
|
+
print(` ${yellow('LinkedIn is a content farm with a jobs tab. This is the profile.')}`);
|
|
230
|
+
print(` ${dim('Applications take 30 minutes. The no takes 400ms.')}`);
|
|
231
|
+
print(` ${dim('Recruiters book the call so they have something to cancel.')}`);
|
|
232
|
+
print(` ${dim('I still do not know their coffee, their mug, or their star sign.')}`);
|
|
232
233
|
};
|
|
233
234
|
|
|
234
235
|
export const toJson = () =>
|