taskair-cli 1.0.7 → 1.0.9

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/package.json CHANGED
@@ -1,13 +1,14 @@
1
1
  {
2
2
  "name": "taskair-cli",
3
- "version": "1.0.7",
3
+ "version": "1.0.9",
4
4
  "description": "Space-themed, privacy-first task management CLI with E2E encryption",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "taskair": "dist/index.js"
8
8
  },
9
9
  "files": [
10
- "dist"
10
+ "dist",
11
+ "scripts"
11
12
  ],
12
13
  "publishConfig": {
13
14
  "access": "public"
@@ -37,7 +38,8 @@
37
38
  "build": "tsup src/index.ts --format esm --dts --out-dir dist --shims",
38
39
  "start": "node dist/index.js",
39
40
  "lint": "tsc --noEmit",
40
- "taskair": "node --import tsx/esm src/index.ts"
41
+ "taskair": "node --import tsx/esm src/index.ts",
42
+ "postinstall": "node scripts/postinstall.js"
41
43
  },
42
44
  "dependencies": {
43
45
  "chalk": "^5.3.0",
@@ -0,0 +1,168 @@
1
+ import readline from 'readline';
2
+
3
+ const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms));
4
+
5
+ const SEQUENCE = [
6
+ { type: 'divider' },
7
+ {
8
+ type: 'bar',
9
+ labels: ['Scanning…', 'Analysing…', 'Detecting…', 'Profiling…'],
10
+ icons: ['✦', '◆', '✶', '❋', '✸'],
11
+ duration: 3000,
12
+ tokenTarget: 0.6, // shows "0.6k" counter
13
+ showPercent: true,
14
+ },
15
+ {
16
+ type: 'lines',
17
+ lines: ['New Role Detected', 'New Team Detected', 'New Challenges'],
18
+ },
19
+ { type: 'divider' },
20
+ {
21
+ type: 'bar',
22
+ labels: ['Booting…', 'Loading…', 'Preparing…', 'Initializing…'],
23
+ icons: ['✦', '◆', '✶', '❋', '✸'],
24
+ duration: 3000,
25
+ showPercent: false, // no percent, no tokens — clean spinner
26
+ },
27
+ { type: 'message', text: "Let's build something great 🚀" },
28
+ { type: 'divider' },
29
+ {
30
+ type: 'bar',
31
+ labels: ['Syncing…', 'Configuring…', 'Setting up…', 'Onboarding…'],
32
+ icons: ['◈', '◉', '⬡', '⬢', '◍'],
33
+ duration: 3000,
34
+ tokenTarget: 0.8, // tokens but no percent
35
+ showPercent: false,
36
+ },
37
+ ];
38
+
39
+ const BG_COLOR = '\x1b[48;2;15;14;23m';
40
+ const RESET = '\x1b[0m';
41
+
42
+ function stripAnsi(str) {
43
+ return str.replace(/\x1b\[[0-9;]*[a-zA-Z]/g, '');
44
+ }
45
+
46
+ function printLine(contentStr = '') {
47
+ const rawLen = stripAnsi(contentStr).length;
48
+ const totalWidth = 52;
49
+ const paddingLeft = 4;
50
+ const paddingRight = Math.max(0, totalWidth - paddingLeft - rawLen);
51
+ const leftSpaces = ' '.repeat(paddingLeft);
52
+ const rightSpaces = ' '.repeat(paddingRight);
53
+ console.log(`${BG_COLOR}${leftSpaces}${contentStr}${rightSpaces}${RESET}`);
54
+ }
55
+
56
+ function printLineInPlace(contentStr) {
57
+ const rawLen = stripAnsi(contentStr).length;
58
+ const totalWidth = 52;
59
+ const paddingLeft = 4;
60
+ const paddingRight = Math.max(0, totalWidth - paddingLeft - rawLen);
61
+ const leftSpaces = ' '.repeat(paddingLeft);
62
+ const rightSpaces = ' '.repeat(paddingRight);
63
+ process.stdout.write(`\r${BG_COLOR}${leftSpaces}${contentStr}${rightSpaces}${RESET}`);
64
+ }
65
+
66
+ async function drawDivider() {
67
+ const line = '─'.repeat(44);
68
+ const dividerStr = `\x1b[38;2;54;49;69m${line}\x1b[0m`;
69
+ printLine(dividerStr);
70
+ await delay(80);
71
+ }
72
+
73
+ async function typeLines(lines) {
74
+ for (const line of lines) {
75
+ for (let i = 1; i <= line.length; i++) {
76
+ const textSoFar = line.slice(0, i);
77
+ const cursor = i < line.length ? '▊' : '';
78
+ const contentStr = `\x1b[38;2;230;230;235m${textSoFar}${cursor}\x1b[0m`;
79
+ printLineInPlace(contentStr);
80
+ await delay(40);
81
+ }
82
+ process.stdout.write('\n');
83
+ await delay(200);
84
+ }
85
+ }
86
+
87
+ async function printMessage(text) {
88
+ const contentStr = `\x1b[1m\x1b[38;2;160;130;255m${text}\x1b[0m`;
89
+ printLine(contentStr);
90
+ await delay(400);
91
+ }
92
+
93
+ async function runProgressBar(phase) {
94
+ const { labels, icons, duration, tokenTarget, showPercent = true } = phase;
95
+ const startTime = Date.now();
96
+
97
+ while (true) {
98
+ const elapsed = Date.now() - startTime;
99
+ const progress = Math.min(1, elapsed / duration);
100
+
101
+ const labelIdx = Math.min(
102
+ labels.length - 1,
103
+ Math.floor(progress * labels.length)
104
+ );
105
+ const label = labels[labelIdx];
106
+
107
+ const iconIdx = Math.floor((Date.now() / 150) % icons.length);
108
+ const icon = icons[iconIdx];
109
+
110
+ const barWidth = 16;
111
+ const filledWidth = Math.floor(progress * barWidth);
112
+ const emptyWidth = barWidth - filledWidth;
113
+ const filledStr = `\x1b[38;2;160;130;255m${'█'.repeat(filledWidth)}\x1b[0m`;
114
+ const emptyStr = `\x1b[38;2;54;49;69m${'░'.repeat(emptyWidth)}\x1b[0m`;
115
+ const barStr = `\x1b[38;2;54;49;69m[\x1b[0m${filledStr}${emptyStr}\x1b[38;2;54;49;69m]\x1b[0m`;
116
+
117
+ let suffix = '';
118
+ if (showPercent) {
119
+ const pct = Math.round(progress * 100);
120
+ suffix += ` \x1b[38;2;160;130;255m${pct}%\x1b[0m`;
121
+ }
122
+
123
+ if (tokenTarget !== undefined) {
124
+ const currentTokens = (progress * tokenTarget).toFixed(1);
125
+ suffix += ` \x1b[38;2;210;190;255m ${currentTokens}k tokens\x1b[0m`;
126
+ }
127
+
128
+ const iconColor = `\x1b[38;2;160;130;255m`;
129
+ const labelColor = `\x1b[1m\x1b[38;2;255;255;255m`;
130
+ const output = `${iconColor}${icon}\x1b[0m ${labelColor}${label.padEnd(14)}\x1b[0m${barStr}${suffix}`;
131
+
132
+ printLineInPlace(output);
133
+
134
+ if (progress >= 1) {
135
+ process.stdout.write('\n');
136
+ break;
137
+ }
138
+
139
+ await delay(80);
140
+ }
141
+ }
142
+
143
+ async function run() {
144
+ console.log('\n\x1b[1m\x1b[38;2;160;130;255m✦ Preparing TaskAir CLI Environment... ✦\x1b[0m\n');
145
+
146
+ printLine();
147
+ printLine();
148
+
149
+ for (const step of SEQUENCE) {
150
+ if (step.type === 'divider') {
151
+ await drawDivider();
152
+ } else if (step.type === 'bar') {
153
+ await runProgressBar(step);
154
+ await delay(150);
155
+ } else if (step.type === 'lines') {
156
+ await typeLines(step.lines);
157
+ } else if (step.type === 'message') {
158
+ await printMessage(step.text);
159
+ }
160
+ }
161
+
162
+ printLine();
163
+ printLine();
164
+
165
+ console.log();
166
+ }
167
+
168
+ run();