devgrowth 1.0.1 → 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 +135 -111
- package/package.json +52 -48
- package/src/commands/config.js +54 -50
- package/src/commands/dashboard.js +13 -0
- package/src/commands/history.js +75 -73
- package/src/commands/log.js +40 -36
- package/src/commands/login.js +127 -0
- package/src/commands/logout.js +26 -0
- package/src/commands/milestone.js +54 -51
- package/src/commands/review.js +62 -57
- package/src/commands/start.js +97 -91
- package/src/commands/status.js +55 -53
- package/src/commands/sync.js +29 -0
- package/src/core/apiClient.js +46 -0
- package/src/core/auth.js +34 -0
- package/src/core/banner.js +293 -293
- package/src/core/configManager.js +57 -70
- package/src/core/eventLog.js +112 -0
- package/src/core/logger.js +62 -62
- package/src/core/milestones.js +62 -72
- package/src/core/prompt.js +58 -0
- package/src/core/rebuild.js +37 -0
- package/src/core/schedule.js +1 -70
- package/src/core/stats.js +43 -130
- package/src/core/storage.js +52 -33
- package/src/core/sync.js +101 -0
- package/src/index.js +221 -152
package/src/index.js
CHANGED
|
@@ -1,152 +1,221 @@
|
|
|
1
|
-
import { Command } from 'commander';
|
|
2
|
-
import { initCommand } from './commands/init.js';
|
|
3
|
-
import { startCommand } from './commands/start.js';
|
|
4
|
-
import { logCommand } from './commands/log.js';
|
|
5
|
-
import { statusCommand } from './commands/status.js';
|
|
6
|
-
import { reviewCommand } from './commands/review.js';
|
|
7
|
-
import { milestoneCommand } from './commands/milestone.js';
|
|
8
|
-
import { historyCommand } from './commands/history.js';
|
|
9
|
-
import { configCommand } from './commands/config.js';
|
|
10
|
-
import { notifyCommand } from './commands/notify.js';
|
|
11
|
-
import {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
.
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
.
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
.
|
|
120
|
-
.
|
|
121
|
-
.
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { initCommand } from './commands/init.js';
|
|
3
|
+
import { startCommand } from './commands/start.js';
|
|
4
|
+
import { logCommand } from './commands/log.js';
|
|
5
|
+
import { statusCommand } from './commands/status.js';
|
|
6
|
+
import { reviewCommand } from './commands/review.js';
|
|
7
|
+
import { milestoneCommand } from './commands/milestone.js';
|
|
8
|
+
import { historyCommand } from './commands/history.js';
|
|
9
|
+
import { configCommand } from './commands/config.js';
|
|
10
|
+
import { notifyCommand } from './commands/notify.js';
|
|
11
|
+
import { loginCommand, registerCommand } from './commands/login.js';
|
|
12
|
+
import { logoutCommand } from './commands/logout.js';
|
|
13
|
+
import { syncCommand } from './commands/sync.js';
|
|
14
|
+
import { dashboardCommand } from './commands/dashboard.js';
|
|
15
|
+
import { printBanner, VERSION } from './core/banner.js';
|
|
16
|
+
|
|
17
|
+
export const program = new Command();
|
|
18
|
+
|
|
19
|
+
program
|
|
20
|
+
.name('devgrowth')
|
|
21
|
+
.description('Zero-friction developer growth CLI')
|
|
22
|
+
.version(VERSION);
|
|
23
|
+
|
|
24
|
+
// Bare `devgrowth` is the splash screen: banner, then the command list.
|
|
25
|
+
program.action(async () => {
|
|
26
|
+
await printBanner();
|
|
27
|
+
program.outputHelp();
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
program
|
|
31
|
+
.command('banner')
|
|
32
|
+
.description('Show the DevGrowth banner and current stats')
|
|
33
|
+
.option('--compact', 'Render the single-line banner')
|
|
34
|
+
.action(async (options) => {
|
|
35
|
+
try {
|
|
36
|
+
await printBanner({ force: true, compact: options.compact });
|
|
37
|
+
} catch (err) {
|
|
38
|
+
console.error('Error:', err.message);
|
|
39
|
+
process.exit(1);
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
program
|
|
44
|
+
.command('init')
|
|
45
|
+
.description('Initialize DevGrowth configuration and directories')
|
|
46
|
+
.action(async () => {
|
|
47
|
+
try {
|
|
48
|
+
await initCommand();
|
|
49
|
+
} catch (err) {
|
|
50
|
+
console.error('Error:', err.message);
|
|
51
|
+
process.exit(1);
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
program
|
|
56
|
+
.command('start')
|
|
57
|
+
.description('Start tonight\'s session')
|
|
58
|
+
.option('--light', 'Skip timer for low-energy sessions')
|
|
59
|
+
.option('--no-banner', 'Skip the startup banner')
|
|
60
|
+
.action(async (options) => {
|
|
61
|
+
try {
|
|
62
|
+
await startCommand(options);
|
|
63
|
+
} catch (err) {
|
|
64
|
+
console.error('Error:', err.message);
|
|
65
|
+
process.exit(1);
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
program
|
|
70
|
+
.command('log <message>')
|
|
71
|
+
.description('Write your 2-sentence session log')
|
|
72
|
+
.option('--light', 'Mark as light session')
|
|
73
|
+
.action(async (message, options) => {
|
|
74
|
+
try {
|
|
75
|
+
await logCommand(message, options);
|
|
76
|
+
} catch (err) {
|
|
77
|
+
console.error('Error:', err.message);
|
|
78
|
+
process.exit(1);
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
program
|
|
83
|
+
.command('status')
|
|
84
|
+
.description('Show this week\'s progress and streak')
|
|
85
|
+
.action(async () => {
|
|
86
|
+
try {
|
|
87
|
+
await statusCommand();
|
|
88
|
+
} catch (err) {
|
|
89
|
+
console.error('Error:', err.message);
|
|
90
|
+
process.exit(1);
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
program
|
|
95
|
+
.command('review')
|
|
96
|
+
.description('Review this week and finalize streak')
|
|
97
|
+
.action(async () => {
|
|
98
|
+
try {
|
|
99
|
+
await reviewCommand();
|
|
100
|
+
} catch (err) {
|
|
101
|
+
console.error('Error:', err.message);
|
|
102
|
+
process.exit(1);
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
program
|
|
107
|
+
.command('milestone <subcommand> [args...]')
|
|
108
|
+
.description('Milestone tracker: list, check, progress')
|
|
109
|
+
.action(async (subcommand, args) => {
|
|
110
|
+
try {
|
|
111
|
+
await milestoneCommand(subcommand, args || []);
|
|
112
|
+
} catch (err) {
|
|
113
|
+
console.error('Error:', err.message);
|
|
114
|
+
process.exit(1);
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
program
|
|
119
|
+
.command('history')
|
|
120
|
+
.description('Show session history')
|
|
121
|
+
.option('--week <number>', 'Show specific week')
|
|
122
|
+
.option('--year <number>', 'Year for --week (defaults to current year)')
|
|
123
|
+
.option('--skill <name>', 'Filter by skill')
|
|
124
|
+
.option('--search <query>', 'Full-text search across logs')
|
|
125
|
+
.action(async (options) => {
|
|
126
|
+
try {
|
|
127
|
+
await historyCommand(options);
|
|
128
|
+
} catch (err) {
|
|
129
|
+
console.error('Error:', err.message);
|
|
130
|
+
process.exit(1);
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
program
|
|
135
|
+
.command('config <subcommand> [args...]')
|
|
136
|
+
.description('Configuration: show, set, edit')
|
|
137
|
+
.action(async (subcommand, args) => {
|
|
138
|
+
try {
|
|
139
|
+
await configCommand(subcommand, args || []);
|
|
140
|
+
} catch (err) {
|
|
141
|
+
console.error('Error:', err.message);
|
|
142
|
+
process.exit(1);
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
program
|
|
147
|
+
.command('notify')
|
|
148
|
+
.description('Send tonight\'s desktop notification (internal use)')
|
|
149
|
+
.action(async () => {
|
|
150
|
+
try {
|
|
151
|
+
await notifyCommand();
|
|
152
|
+
} catch (err) {
|
|
153
|
+
console.error('Error:', err.message);
|
|
154
|
+
process.exit(1);
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
program
|
|
159
|
+
.command('register')
|
|
160
|
+
.description('Create a sync account and connect this device')
|
|
161
|
+
.option('--api <url>', 'Sync server URL (default: $DEVGROWTH_API_URL or http://localhost:3000)')
|
|
162
|
+
.option('--email <email>', 'Account email (prompted if omitted)')
|
|
163
|
+
.action(async (options) => {
|
|
164
|
+
try {
|
|
165
|
+
await registerCommand(options);
|
|
166
|
+
} catch (err) {
|
|
167
|
+
console.error('Error:', err.message);
|
|
168
|
+
process.exit(1);
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
program
|
|
173
|
+
.command('login')
|
|
174
|
+
.description('Connect this device to your sync account')
|
|
175
|
+
.option('--api <url>', 'Sync server URL (default: $DEVGROWTH_API_URL or http://localhost:3000)')
|
|
176
|
+
.option('--email <email>', 'Account email (prompted if omitted)')
|
|
177
|
+
.action(async (options) => {
|
|
178
|
+
try {
|
|
179
|
+
await loginCommand(options);
|
|
180
|
+
} catch (err) {
|
|
181
|
+
console.error('Error:', err.message);
|
|
182
|
+
process.exit(1);
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
program
|
|
187
|
+
.command('logout')
|
|
188
|
+
.description('Disconnect this device from sync (local data is kept)')
|
|
189
|
+
.action(async () => {
|
|
190
|
+
try {
|
|
191
|
+
await logoutCommand();
|
|
192
|
+
} catch (err) {
|
|
193
|
+
console.error('Error:', err.message);
|
|
194
|
+
process.exit(1);
|
|
195
|
+
}
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
program
|
|
199
|
+
.command('sync [subcommand]')
|
|
200
|
+
.description('Sync now, or `sync status` to see pending changes')
|
|
201
|
+
.action(async (subcommand) => {
|
|
202
|
+
try {
|
|
203
|
+
await syncCommand(subcommand);
|
|
204
|
+
} catch (err) {
|
|
205
|
+
console.error('Error:', err.message);
|
|
206
|
+
process.exit(1);
|
|
207
|
+
}
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
program
|
|
211
|
+
.command('dashboard')
|
|
212
|
+
.description('Open the web dashboard')
|
|
213
|
+
.option('--api <url>', 'Sync server URL')
|
|
214
|
+
.action(async (options) => {
|
|
215
|
+
try {
|
|
216
|
+
await dashboardCommand(options);
|
|
217
|
+
} catch (err) {
|
|
218
|
+
console.error('Error:', err.message);
|
|
219
|
+
process.exit(1);
|
|
220
|
+
}
|
|
221
|
+
});
|