adityashinde 0.0.2 → 0.0.5
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/index.js +515 -130
- package/package.json +18 -4
package/index.js
CHANGED
|
@@ -1,142 +1,527 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
const readline = require("readline")
|
|
4
|
-
|
|
5
|
-
function header() {
|
|
6
|
-
console.clear()
|
|
7
|
-
console.log(`
|
|
8
|
-
────────────────────────────────
|
|
9
|
-
Aditya Shinde
|
|
10
|
-
Founder, Web Designer at Kala
|
|
11
|
-
────────────────────────────────
|
|
12
|
-
`)
|
|
13
|
-
}
|
|
1
|
+
#!/usr/bin/env node
|
|
14
2
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
console.log(`
|
|
18
|
-
I design and build clean, modern web experiences
|
|
19
|
-
with a strong focus on UI, motion, and systems.
|
|
20
|
-
|
|
21
|
-
Type one of the following and press Enter:
|
|
22
|
-
about
|
|
23
|
-
website
|
|
24
|
-
github
|
|
25
|
-
socials
|
|
26
|
-
resume
|
|
27
|
-
help
|
|
28
|
-
exit
|
|
29
|
-
`)
|
|
30
|
-
}
|
|
3
|
+
import readline from "readline";
|
|
4
|
+
import process from "process";
|
|
31
5
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
─────
|
|
37
|
-
I’m Aditya Shinde, a web designer & front-end developer
|
|
38
|
-
focused on minimal UI, motion, and modern systems.
|
|
39
|
-
|
|
40
|
-
Portfolio : https://www.adityashinde.in
|
|
41
|
-
Studio : https://www.trykala.com
|
|
42
|
-
Location : India
|
|
43
|
-
`)
|
|
6
|
+
// Enable keypress on stdin
|
|
7
|
+
readline.emitKeypressEvents(process.stdin);
|
|
8
|
+
if (process.stdin.setRawMode) {
|
|
9
|
+
process.stdin.setRawMode(true);
|
|
44
10
|
}
|
|
45
11
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
───────
|
|
51
|
-
https://www.adityashinde.in
|
|
52
|
-
`)
|
|
53
|
-
}
|
|
12
|
+
// Dynamic imports for ESM-only packages
|
|
13
|
+
const importChalk = () => import('chalk');
|
|
14
|
+
const importBoxen = () => import('boxen');
|
|
15
|
+
const importOpen = () => import('open');
|
|
54
16
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
GitHub
|
|
59
|
-
──────
|
|
60
|
-
https://github.com/adityashinde-in
|
|
61
|
-
`)
|
|
62
|
-
}
|
|
17
|
+
// STATE MANAGEMENT
|
|
18
|
+
let lastLink = null;
|
|
19
|
+
let lastLinks = null;
|
|
63
20
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
}
|
|
21
|
+
// DATA & CONTENT
|
|
22
|
+
const data = {
|
|
23
|
+
about: {
|
|
24
|
+
aliases: ['about', 'bio', 'who', 'intro', 'background', 'aditya', 'me', 'info'],
|
|
25
|
+
text: (chalk) => {
|
|
26
|
+
return `
|
|
27
|
+
${chalk.bold.hex('#00d4ff')("Aditya Shinde")}
|
|
28
|
+
${chalk.dim("Founder · Web Designer & Front-end Developer")}
|
|
73
29
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
30
|
+
• Started my creative journey at ${chalk.blue("Kalakruti")} (family print & branding business, est. 1996)
|
|
31
|
+
• Learned fundamentals of branding, consistency, and long-term visual quality there
|
|
32
|
+
• I run ${chalk.bold("Kala")} - a creative web studio
|
|
33
|
+
• I build custom-coded websites (no templates, no page builders)
|
|
34
|
+
• I work hands-on across design, development, and direction
|
|
35
|
+
• I believe in lean systems, clarity, and future-ready builds
|
|
36
|
+
`;
|
|
37
|
+
},
|
|
38
|
+
link: 'https://www.adityashinde.in'
|
|
39
|
+
},
|
|
40
|
+
|
|
41
|
+
skills: {
|
|
42
|
+
aliases: ['skills', 'stack', 'tech', 'expert', 'skill', 'technology', 'experience'],
|
|
43
|
+
text: (chalk) => `
|
|
44
|
+
${chalk.bold("Design")}
|
|
45
|
+
─────────
|
|
46
|
+
• UI/UX for the web
|
|
47
|
+
• Visual identity systems
|
|
48
|
+
• Typography & layout
|
|
49
|
+
• Motion-first interfaces
|
|
83
50
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
51
|
+
${chalk.bold("Development")}
|
|
52
|
+
──────────────
|
|
53
|
+
• HTML, CSS, JavaScript
|
|
54
|
+
• Clean, scalable front-end architecture
|
|
55
|
+
• Animation & interaction (GSAP)
|
|
56
|
+
• Performance-focused builds
|
|
57
|
+
|
|
58
|
+
${chalk.bold("Systems")}
|
|
59
|
+
──────────
|
|
60
|
+
• CMS integration
|
|
61
|
+
• SEO-friendly structure
|
|
62
|
+
• Long-term maintainability
|
|
63
|
+
`
|
|
64
|
+
},
|
|
65
|
+
|
|
66
|
+
projects: {
|
|
67
|
+
aliases: ['projects', 'work', 'clients', 'portfolio', 'project', 'client'],
|
|
68
|
+
text: (chalk) => `
|
|
69
|
+
${chalk.bold("Selected Work")}
|
|
70
|
+
──────────────
|
|
71
|
+
I keep my work curated and updated here:
|
|
72
|
+
|
|
73
|
+
${chalk.underline.cyan("https://trykala.com/projects/")}
|
|
74
|
+
|
|
75
|
+
Each project is custom built - no templates, no shortcuts.
|
|
76
|
+
`,
|
|
77
|
+
link: 'https://trykala.com/projects/'
|
|
78
|
+
},
|
|
79
|
+
|
|
80
|
+
website: {
|
|
81
|
+
aliases: ['website', 'site', 'web', 'url', 'homepage', 'websites', 'sites', 'webpage', 'page'],
|
|
82
|
+
text: (chalk) => `
|
|
83
|
+
${chalk.bold("Personal Portfolio")}
|
|
84
|
+
──────────────────────
|
|
85
|
+
${chalk.underline.cyan("https://www.adityashinde.in")}
|
|
86
|
+
|
|
87
|
+
${chalk.bold("Studio Website")}
|
|
88
|
+
──────────────────────
|
|
89
|
+
${chalk.underline.cyan("https://trykala.com")}
|
|
90
|
+
`,
|
|
91
|
+
links: [
|
|
92
|
+
{ title: "Personal Portfolio", url: "https://www.adityashinde.in" },
|
|
93
|
+
{ title: "Studio Website", url: "https://trykala.com" }
|
|
94
|
+
]
|
|
95
|
+
},
|
|
96
|
+
|
|
97
|
+
github: {
|
|
98
|
+
aliases: ['github', 'git', 'code', 'repo', 'repos', 'repository', 'source'],
|
|
99
|
+
text: (chalk) => `
|
|
100
|
+
${chalk.bold("GitHub Profile")}
|
|
101
|
+
──────────────
|
|
102
|
+
${chalk.underline.cyan("https://github.com/adityashinde-in")}
|
|
103
|
+
`,
|
|
104
|
+
link: 'https://github.com/adityashinde-in'
|
|
105
|
+
},
|
|
106
|
+
|
|
107
|
+
behance: {
|
|
108
|
+
aliases: ['behance', 'be', 'design', 'portfolio'],
|
|
109
|
+
text: (chalk) => `
|
|
110
|
+
${chalk.bold("Behance Portfolio")}
|
|
111
|
+
─────────────────
|
|
112
|
+
${chalk.underline.cyan("https://www.behance.net/adityashinde_in")}
|
|
113
|
+
`,
|
|
114
|
+
link: 'https://www.behance.net/adityashinde_in'
|
|
115
|
+
},
|
|
116
|
+
|
|
117
|
+
linkedin: {
|
|
118
|
+
aliases: ['linkedin', 'linked', 'professional', 'network'],
|
|
119
|
+
text: (chalk) => `
|
|
120
|
+
${chalk.bold("LinkedIn Profile")}
|
|
121
|
+
─────────────────
|
|
122
|
+
${chalk.underline.cyan("https://www.linkedin.com/in/adityashinde-in")}
|
|
123
|
+
`,
|
|
124
|
+
link: 'https://www.linkedin.com/in/adityashinde-in'
|
|
125
|
+
},
|
|
126
|
+
|
|
127
|
+
instagram: {
|
|
128
|
+
aliases: ['instagram', 'ig', 'insta', 'photos', 'visuals'],
|
|
129
|
+
text: (chalk) => `
|
|
130
|
+
${chalk.bold("Instagram Profile")}
|
|
131
|
+
─────────────────
|
|
132
|
+
${chalk.underline.cyan("https://www.instagram.com/adityashinde_in")}
|
|
133
|
+
`,
|
|
134
|
+
link: 'https://www.instagram.com/adityashinde_in'
|
|
135
|
+
},
|
|
136
|
+
|
|
137
|
+
chess: {
|
|
138
|
+
aliases: ['chess', 'chess.com', 'game', 'games'],
|
|
139
|
+
text: (chalk) => `
|
|
140
|
+
${chalk.bold("Chess Profile")}
|
|
141
|
+
─────────────────
|
|
142
|
+
${chalk.underline.cyan("https://www.chess.com/member/adityashinde_in")}
|
|
143
|
+
`,
|
|
144
|
+
link: 'https://www.chess.com/member/adityashinde_in'
|
|
145
|
+
},
|
|
146
|
+
|
|
147
|
+
socials: {
|
|
148
|
+
aliases: ['socials', 'social', 'contact', 'contacts', 'email', 'call', 'reach', 'connect', 'socialmedia', 'all'],
|
|
149
|
+
text: (chalk) => `
|
|
150
|
+
${chalk.bold("Connect With Me")}
|
|
151
|
+
─────────────────
|
|
152
|
+
Email : ${chalk.cyan("aditya@trykala.com")}
|
|
153
|
+
: ${chalk.cyan("hi@adityashinde.in")}
|
|
154
|
+
|
|
155
|
+
${chalk.bold("Social Platforms")}
|
|
156
|
+
─────────────────
|
|
157
|
+
Behance : ${chalk.cyan("behance.net/adityashinde_in")}
|
|
158
|
+
Instagram : ${chalk.cyan("instagram.com/adityashinde_in")}
|
|
159
|
+
LinkedIn : ${chalk.cyan("linkedin.com/in/adityashinde-in")}
|
|
160
|
+
GitHub : ${chalk.cyan("github.com/adityashinde-in")}
|
|
161
|
+
Chess : ${chalk.cyan("chess.com/member/adityashinde_in")}
|
|
162
|
+
`,
|
|
163
|
+
links: [
|
|
164
|
+
{ title: "Email - aditya@trykala.com", url: "mailto:aditya@trykala.com" },
|
|
165
|
+
{ title: "Email - hi@adityashinde.in", url: "mailto:hi@adityashinde.in" },
|
|
166
|
+
{ title: "Behance", url: "https://www.behance.net/adityashinde_in" },
|
|
167
|
+
{ title: "Instagram", url: "https://www.instagram.com/adityashinde_in" },
|
|
168
|
+
{ title: "LinkedIn", url: "https://www.linkedin.com/in/adityashinde-in" },
|
|
169
|
+
{ title: "GitHub", url: "https://github.com/adityashinde-in" },
|
|
170
|
+
{ title: "Chess", url: "https://www.chess.com/member/adityashinde_in" }
|
|
171
|
+
]
|
|
172
|
+
},
|
|
173
|
+
|
|
174
|
+
studio: {
|
|
175
|
+
aliases: ['studio', 'kala', 'work', 'business', 'company', 'agency', 'service'],
|
|
176
|
+
text: (chalk) => `
|
|
177
|
+
${chalk.bold("Hey! This is my website")}
|
|
178
|
+
${chalk.dim("We create premium websites here, check it out")}
|
|
179
|
+
|
|
180
|
+
${chalk.underline.cyan("https://trykala.com")}
|
|
181
|
+
`,
|
|
182
|
+
link: 'https://trykala.com'
|
|
183
|
+
},
|
|
184
|
+
|
|
185
|
+
help: {
|
|
186
|
+
aliases: ['help', 'commands', 'menu', 'list', 'ls', 'command', 'cmds'],
|
|
187
|
+
action: 'help'
|
|
188
|
+
},
|
|
189
|
+
|
|
190
|
+
philosophy: {
|
|
191
|
+
aliases: ['philosophy', 'principles', 'mindset', 'values', 'principle', 'value'],
|
|
192
|
+
text: (chalk) => `
|
|
193
|
+
${chalk.bold("Design Philosophy")}
|
|
194
|
+
─────────────────
|
|
195
|
+
• Clarity over complexity
|
|
196
|
+
• Custom code over convenience
|
|
197
|
+
• Motion with purpose
|
|
198
|
+
• Design that ages well
|
|
199
|
+
• Fewer features, done properly
|
|
200
|
+
`
|
|
201
|
+
},
|
|
202
|
+
|
|
203
|
+
resume: {
|
|
204
|
+
aliases: ['resume', 'cv', 'experience', 'curriculum'],
|
|
205
|
+
text: (chalk) => `
|
|
206
|
+
${chalk.bold("Resume")}
|
|
207
|
+
───────────────
|
|
208
|
+
|
|
209
|
+
${chalk.bold("Role:")}
|
|
210
|
+
Founder, Web Designer & Front-end Developer
|
|
211
|
+
|
|
212
|
+
${chalk.bold("Studio:")}
|
|
213
|
+
Kala - Creative Web Studio
|
|
214
|
+
|
|
215
|
+
${chalk.bold("What I Do:")}
|
|
216
|
+
• Design and build custom websites
|
|
217
|
+
• Define visual systems for digital brands
|
|
218
|
+
• Oversee projects end-to-end
|
|
219
|
+
• Handle client communication & direction
|
|
220
|
+
|
|
221
|
+
${chalk.bold("Background:")}
|
|
222
|
+
• Roots in print & branding (Kalakruti)
|
|
223
|
+
• Transitioned into modern web & interaction design
|
|
224
|
+
• Independent studio founder handling real client work
|
|
96
225
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
rl.on("line", (input) => {
|
|
107
|
-
const command = input.trim().toLowerCase()
|
|
108
|
-
|
|
109
|
-
switch (command) {
|
|
110
|
-
case "about":
|
|
111
|
-
about()
|
|
112
|
-
break
|
|
113
|
-
case "website":
|
|
114
|
-
website()
|
|
115
|
-
break
|
|
116
|
-
case "github":
|
|
117
|
-
github()
|
|
118
|
-
break
|
|
119
|
-
case "socials":
|
|
120
|
-
socials()
|
|
121
|
-
break
|
|
122
|
-
case "resume":
|
|
123
|
-
resume()
|
|
124
|
-
break
|
|
125
|
-
case "help":
|
|
126
|
-
help()
|
|
127
|
-
break
|
|
128
|
-
case "exit":
|
|
129
|
-
rl.close()
|
|
130
|
-
return
|
|
131
|
-
default:
|
|
132
|
-
console.log("Unknown command. Type help to see options.")
|
|
226
|
+
${chalk.bold("Focus / Future:")}
|
|
227
|
+
Building Kala into a trusted platform for a growing global audience,
|
|
228
|
+
serving brands that value long-term digital quality.
|
|
229
|
+
`
|
|
230
|
+
},
|
|
231
|
+
|
|
232
|
+
exit: {
|
|
233
|
+
aliases: ['exit', 'quit', 'bye', 'close', 'end', 'stop'],
|
|
234
|
+
action: 'exit'
|
|
133
235
|
}
|
|
236
|
+
};
|
|
134
237
|
|
|
135
|
-
|
|
136
|
-
})
|
|
238
|
+
async function main() {
|
|
239
|
+
const { default: chalk } = await importChalk();
|
|
240
|
+
const { default: boxen } = await importBoxen();
|
|
241
|
+
const { default: open } = await importOpen();
|
|
242
|
+
|
|
243
|
+
// Check for command-line arguments for direct commands
|
|
244
|
+
const args = process.argv.slice(2);
|
|
245
|
+
if (args.length > 0) {
|
|
246
|
+
const command = args[0].toLowerCase();
|
|
247
|
+
|
|
248
|
+
// Handle 'open' command for direct mode
|
|
249
|
+
if (command === 'open') {
|
|
250
|
+
console.log(chalk.red("\n'open' command only works in interactive mode."));
|
|
251
|
+
console.log(chalk.dim("Run 'adityashinde' without arguments to enter interactive mode."));
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
let foundKey = null;
|
|
256
|
+
for (const key in data) {
|
|
257
|
+
if (data[key].aliases.includes(command)) {
|
|
258
|
+
foundKey = key;
|
|
259
|
+
break;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
if (foundKey) {
|
|
264
|
+
const item = data[foundKey];
|
|
265
|
+
|
|
266
|
+
if (item.action === 'exit') {
|
|
267
|
+
process.exit(0);
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
if (item.action === 'help') {
|
|
271
|
+
console.log(chalk.bold("\n COMMANDS"));
|
|
272
|
+
console.log(` ${chalk.cyan("about")} → My Story & Bio`);
|
|
273
|
+
console.log(` ${chalk.cyan("projects")} → Selected Work`);
|
|
274
|
+
console.log(` ${chalk.cyan("skills")} → Design & Development`);
|
|
275
|
+
console.log(` ${chalk.cyan("philosophy")} → Design Principles`);
|
|
276
|
+
console.log(` ${chalk.cyan("resume")} → Resume`);
|
|
277
|
+
console.log(` ${chalk.cyan("studio")} → Visit My Studio Website`);
|
|
278
|
+
console.log(` ${chalk.cyan("website")} → Visit Portfolio`);
|
|
279
|
+
console.log(` ${chalk.cyan("socials")} → All Social Links`);
|
|
280
|
+
console.log(` ${chalk.cyan("behance")} → Behance Portfolio`);
|
|
281
|
+
console.log(` ${chalk.cyan("linkedin")} → LinkedIn Profile`);
|
|
282
|
+
console.log(` ${chalk.cyan("instagram")} → Instagram Profile`);
|
|
283
|
+
console.log(` ${chalk.cyan("chess")} → Chess Profile`);
|
|
284
|
+
console.log(` ${chalk.cyan("github")} → GitHub Profile`);
|
|
285
|
+
console.log(` ${chalk.cyan("open")} → Open last link in browser`);
|
|
286
|
+
console.log(` ${chalk.cyan("exit")} → Quit`);
|
|
287
|
+
console.log("");
|
|
288
|
+
console.log(chalk.dim("Usage: adityashinde [command]"));
|
|
289
|
+
console.log(chalk.dim("Run without arguments for interactive mode."));
|
|
290
|
+
return;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
console.log(boxen(item.text(chalk), {
|
|
294
|
+
padding: 1,
|
|
295
|
+
margin: 0,
|
|
296
|
+
borderStyle: 'classic',
|
|
297
|
+
borderColor: 'gray'
|
|
298
|
+
}));
|
|
299
|
+
|
|
300
|
+
if (item.links && item.links.length > 0) {
|
|
301
|
+
console.log(chalk.dim(`\nAvailable links:`));
|
|
302
|
+
item.links.forEach((link, index) => {
|
|
303
|
+
console.log(chalk.cyan(` ${index + 1}. ${link.title}: ${link.url}`));
|
|
304
|
+
});
|
|
305
|
+
console.log(chalk.dim(`\nRun 'adityashinde' for interactive mode to open links`));
|
|
306
|
+
} else if (item.link) {
|
|
307
|
+
console.log(chalk.dim(`\nLink: ${item.link}`));
|
|
308
|
+
console.log(chalk.dim(`Run 'adityashinde' for interactive mode to open link`));
|
|
309
|
+
}
|
|
310
|
+
} else {
|
|
311
|
+
console.log(chalk.red(`Unknown command: ${command}`));
|
|
312
|
+
console.log(chalk.dim("Run 'adityashinde help' for available commands."));
|
|
313
|
+
}
|
|
314
|
+
return;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
const rl = readline.createInterface({
|
|
318
|
+
input: process.stdin,
|
|
319
|
+
output: process.stdout,
|
|
320
|
+
prompt: chalk.cyan.bold("➜ ")
|
|
321
|
+
});
|
|
322
|
+
|
|
323
|
+
function showHeader() {
|
|
324
|
+
console.clear();
|
|
325
|
+
console.log(
|
|
326
|
+
boxen(
|
|
327
|
+
chalk.bold.hex('#00d4ff')(" Minimal web designer and developer. ") + "\n" +
|
|
328
|
+
chalk.hex('#aaaaaa')(" Founder of Kala. Building custom-coded digital experiences. "),
|
|
329
|
+
{
|
|
330
|
+
padding: 1,
|
|
331
|
+
margin: 1,
|
|
332
|
+
borderStyle: 'round',
|
|
333
|
+
borderColor: 'cyan',
|
|
334
|
+
title: 'terminal-resume',
|
|
335
|
+
titleAlignment: 'center'
|
|
336
|
+
}
|
|
337
|
+
)
|
|
338
|
+
);
|
|
339
|
+
console.log(chalk.dim("Type help to explore.\n"));
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
function showHelp() {
|
|
343
|
+
console.log(chalk.bold("\n COMMANDS"));
|
|
344
|
+
console.log(` ${chalk.cyan("about")} → My Story & Bio`);
|
|
345
|
+
console.log(` ${chalk.cyan("projects")} → Selected Work`);
|
|
346
|
+
console.log(` ${chalk.cyan("skills")} → Design & Development`);
|
|
347
|
+
console.log(` ${chalk.cyan("philosophy")} → Design Principles`);
|
|
348
|
+
console.log(` ${chalk.cyan("resume")} → Resume`);
|
|
349
|
+
console.log(` ${chalk.cyan("studio")} → Visit My Studio Website`);
|
|
350
|
+
console.log(` ${chalk.cyan("website")} → Visit Portfolio`);
|
|
351
|
+
console.log(` ${chalk.cyan("socials")} → All Social Links`);
|
|
352
|
+
console.log(` ${chalk.cyan("behance")} → Behance Portfolio`);
|
|
353
|
+
console.log(` ${chalk.cyan("linkedin")} → LinkedIn Profile`);
|
|
354
|
+
console.log(` ${chalk.cyan("instagram")} → Instagram Profile`);
|
|
355
|
+
console.log(` ${chalk.cyan("chess")} → Chess Profile`);
|
|
356
|
+
console.log(` ${chalk.cyan("github")} → GitHub Profile`);
|
|
357
|
+
console.log(` ${chalk.cyan("open")} → Open last link in browser`);
|
|
358
|
+
console.log(` ${chalk.cyan("exit")} → Quit`);
|
|
359
|
+
console.log("");
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
function showLinkSelectionMenu(links) {
|
|
363
|
+
return new Promise((resolve) => {
|
|
364
|
+
let selectedIndex = 0;
|
|
365
|
+
let isSelecting = true;
|
|
366
|
+
|
|
367
|
+
// Hide cursor
|
|
368
|
+
process.stdout.write('\x1B[?25l');
|
|
369
|
+
|
|
370
|
+
function renderMenu() {
|
|
371
|
+
// Clear screen and move to top
|
|
372
|
+
process.stdout.write('\x1b[2J\x1b[H');
|
|
373
|
+
|
|
374
|
+
console.log(chalk.bold.cyan("Select a link to open:"));
|
|
375
|
+
console.log("");
|
|
376
|
+
|
|
377
|
+
links.forEach((link, index) => {
|
|
378
|
+
const prefix = index === selectedIndex ? chalk.cyan('› ') : ' ';
|
|
379
|
+
const title = index === selectedIndex ? chalk.bold(link.title) : link.title;
|
|
380
|
+
const url = index === selectedIndex ? chalk.cyan(link.url) : chalk.dim(link.url);
|
|
381
|
+
console.log(`${prefix}${title}`);
|
|
382
|
+
console.log(` ${url}`);
|
|
383
|
+
if (index < links.length - 1) console.log("");
|
|
384
|
+
});
|
|
385
|
+
|
|
386
|
+
console.log("");
|
|
387
|
+
console.log(chalk.dim("Use ↑↓ arrows to navigate, Enter to select, Esc to cancel"));
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
function handleKeypress(char, key) {
|
|
391
|
+
if (!isSelecting) return;
|
|
392
|
+
|
|
393
|
+
if (key.name === 'escape') {
|
|
394
|
+
cleanup();
|
|
395
|
+
console.log(chalk.dim("\nCancelled."));
|
|
396
|
+
resolve(null);
|
|
397
|
+
} else if (key.name === 'return') {
|
|
398
|
+
cleanup();
|
|
399
|
+
resolve(links[selectedIndex]);
|
|
400
|
+
} else if (key.name === 'up') {
|
|
401
|
+
selectedIndex = selectedIndex > 0 ? selectedIndex - 1 : links.length - 1;
|
|
402
|
+
renderMenu();
|
|
403
|
+
} else if (key.name === 'down') {
|
|
404
|
+
selectedIndex = selectedIndex < links.length - 1 ? selectedIndex + 1 : 0;
|
|
405
|
+
renderMenu();
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
function cleanup() {
|
|
410
|
+
isSelecting = false;
|
|
411
|
+
|
|
412
|
+
// Show cursor again
|
|
413
|
+
process.stdout.write('\x1B[?25h');
|
|
414
|
+
|
|
415
|
+
// Remove keypress listener
|
|
416
|
+
process.stdin.removeListener('keypress', handleKeypress);
|
|
417
|
+
|
|
418
|
+
// Restore normal mode
|
|
419
|
+
if (process.stdin.setRawMode) {
|
|
420
|
+
process.stdin.setRawMode(false);
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
// Start listening for keypress events
|
|
425
|
+
process.stdin.on('keypress', handleKeypress);
|
|
426
|
+
|
|
427
|
+
// Initial render
|
|
428
|
+
renderMenu();
|
|
429
|
+
});
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
function handleCommand(input) {
|
|
433
|
+
const rawInput = input.trim().toLowerCase();
|
|
434
|
+
|
|
435
|
+
if (!rawInput) return;
|
|
436
|
+
|
|
437
|
+
if (rawInput === 'open') {
|
|
438
|
+
if (lastLinks && lastLinks.length > 0) {
|
|
439
|
+
showLinkSelectionMenu(lastLinks).then(selectedLink => {
|
|
440
|
+
if (selectedLink) {
|
|
441
|
+
console.log(chalk.yellow(`\nOpening ${selectedLink.title}...`));
|
|
442
|
+
open(selectedLink.url).then(() => {
|
|
443
|
+
console.log(chalk.green(`\nLink opened successfully!`));
|
|
444
|
+
rl.prompt();
|
|
445
|
+
}).catch(() => {
|
|
446
|
+
console.log(chalk.dim(`\nLink opened (if available).`));
|
|
447
|
+
rl.prompt();
|
|
448
|
+
});
|
|
449
|
+
} else {
|
|
450
|
+
rl.prompt();
|
|
451
|
+
}
|
|
452
|
+
});
|
|
453
|
+
return;
|
|
454
|
+
} else if (lastLink) {
|
|
455
|
+
console.log(chalk.yellow(`\nOpening ${lastLink}...`));
|
|
456
|
+
open(lastLink).then(() => {
|
|
457
|
+
console.log(chalk.green(`\nLink opened successfully!`));
|
|
458
|
+
rl.prompt();
|
|
459
|
+
}).catch(() => {
|
|
460
|
+
console.log(chalk.dim(`\nLink opened (if available).`));
|
|
461
|
+
rl.prompt();
|
|
462
|
+
});
|
|
463
|
+
} else {
|
|
464
|
+
console.log(chalk.red("\nNothing to open yet! View 'website' or 'socials' first."));
|
|
465
|
+
rl.prompt();
|
|
466
|
+
}
|
|
467
|
+
return;
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
let foundKey = null;
|
|
471
|
+
for (const key in data) {
|
|
472
|
+
if (data[key].aliases.includes(rawInput)) {
|
|
473
|
+
foundKey = key;
|
|
474
|
+
break;
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
if (foundKey) {
|
|
479
|
+
const item = data[foundKey];
|
|
480
|
+
|
|
481
|
+
if (item.action === 'exit') {
|
|
482
|
+
rl.close();
|
|
483
|
+
return;
|
|
484
|
+
}
|
|
485
|
+
if (item.action === 'help') {
|
|
486
|
+
showHelp();
|
|
487
|
+
return;
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
console.log(boxen(item.text(chalk), {
|
|
491
|
+
padding: 1,
|
|
492
|
+
margin: 0,
|
|
493
|
+
borderStyle: 'classic',
|
|
494
|
+
borderColor: 'gray'
|
|
495
|
+
}));
|
|
496
|
+
|
|
497
|
+
if (item.links && item.links.length > 0) {
|
|
498
|
+
lastLinks = item.links;
|
|
499
|
+
lastLink = null; // Clear single link when multiple links exist
|
|
500
|
+
console.log(chalk.dim(`\n(Type ${chalk.bold.white("open")} to choose a link to launch)`));
|
|
501
|
+
} else if (item.link) {
|
|
502
|
+
lastLink = item.link;
|
|
503
|
+
lastLinks = null; // Clear multiple links when single link exists
|
|
504
|
+
console.log(chalk.dim(`\n(Type ${chalk.bold.white("open")} to launch link)`));
|
|
505
|
+
}
|
|
506
|
+
} else {
|
|
507
|
+
console.log(chalk.red("\nUnknown command."));
|
|
508
|
+
console.log(chalk.dim("Type 'help' for the menu."));
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
showHeader();
|
|
513
|
+
showHelp();
|
|
514
|
+
rl.prompt();
|
|
515
|
+
|
|
516
|
+
rl.on("line", (input) => {
|
|
517
|
+
handleCommand(input);
|
|
518
|
+
rl.prompt();
|
|
519
|
+
});
|
|
520
|
+
|
|
521
|
+
rl.on("close", () => {
|
|
522
|
+
console.log(chalk.cyan("\nThanks for checking out my work! 👋\n"));
|
|
523
|
+
process.exit(0);
|
|
524
|
+
});
|
|
525
|
+
}
|
|
137
526
|
|
|
138
|
-
|
|
139
|
-
console.clear()
|
|
140
|
-
console.log("Thanks for stopping by 👋")
|
|
141
|
-
process.exit(0)
|
|
142
|
-
})
|
|
527
|
+
main();
|
package/package.json
CHANGED
|
@@ -1,10 +1,24 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "adityashinde",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"description": "Aditya Shinde
|
|
3
|
+
"version": "0.0.5",
|
|
4
|
+
"description": "Aditya Shinde - interactive terminal portfolio",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"type": "module",
|
|
5
7
|
"bin": {
|
|
6
8
|
"adityashinde": "index.js"
|
|
7
9
|
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"start": "node index.js"
|
|
12
|
+
},
|
|
8
13
|
"author": "Aditya Shinde",
|
|
9
|
-
"license": "MIT"
|
|
10
|
-
|
|
14
|
+
"license": "MIT",
|
|
15
|
+
"dependencies": {
|
|
16
|
+
"boxen": "^8.0.1",
|
|
17
|
+
"chalk": "^5.3.0",
|
|
18
|
+
"open": "^10.1.0",
|
|
19
|
+
"keypress": "^0.2.1"
|
|
20
|
+
},
|
|
21
|
+
"engines": {
|
|
22
|
+
"node": ">=18.0.0"
|
|
23
|
+
}
|
|
24
|
+
}
|