devclocked 2.1.1 → 2.1.2
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/auth.d.ts +16 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +68 -0
- package/dist/auth.js.map +1 -0
- package/dist/branding/banner.d.ts +16 -0
- package/dist/branding/banner.d.ts.map +1 -0
- package/dist/branding/banner.js +109 -0
- package/dist/branding/banner.js.map +1 -0
- package/dist/branding/dashboard.d.ts +28 -0
- package/dist/branding/dashboard.d.ts.map +1 -0
- package/dist/branding/dashboard.js +508 -0
- package/dist/branding/dashboard.js.map +1 -0
- package/dist/commands/flush.d.ts +6 -0
- package/dist/commands/flush.d.ts.map +1 -0
- package/dist/commands/flush.js +54 -0
- package/dist/commands/flush.js.map +1 -0
- package/dist/commands/login.d.ts +6 -0
- package/dist/commands/login.d.ts.map +1 -0
- package/dist/commands/login.js +108 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/logout.d.ts +6 -0
- package/dist/commands/logout.d.ts.map +1 -0
- package/dist/commands/logout.js +38 -0
- package/dist/commands/logout.js.map +1 -0
- package/dist/commands/mcp-health.d.ts +8 -0
- package/dist/commands/mcp-health.d.ts.map +1 -0
- package/dist/commands/mcp-health.js +75 -0
- package/dist/commands/mcp-health.js.map +1 -0
- package/dist/commands/mcp-server.d.ts +65 -0
- package/dist/commands/mcp-server.d.ts.map +1 -0
- package/dist/commands/mcp-server.js +280 -0
- package/dist/commands/mcp-server.js.map +1 -0
- package/dist/commands/session.d.ts +6 -0
- package/dist/commands/session.d.ts.map +1 -0
- package/dist/commands/session.js +90 -0
- package/dist/commands/session.js.map +1 -0
- package/dist/commands/setup.d.ts +8 -0
- package/dist/commands/setup.d.ts.map +1 -0
- package/dist/commands/setup.js +164 -0
- package/dist/commands/setup.js.map +1 -0
- package/dist/commands/status.d.ts +6 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +78 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/summary.d.ts +6 -0
- package/dist/commands/summary.d.ts.map +1 -0
- package/dist/commands/summary.js +45 -0
- package/dist/commands/summary.js.map +1 -0
- package/dist/config.d.ts +13 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +22 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +40 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp-utils.d.ts +15 -0
- package/dist/mcp-utils.d.ts.map +1 -0
- package/dist/mcp-utils.js +60 -0
- package/dist/mcp-utils.js.map +1 -0
- package/dist/storage/FileStorageAdapter.d.ts +19 -0
- package/dist/storage/FileStorageAdapter.d.ts.map +1 -0
- package/dist/storage/FileStorageAdapter.js +80 -0
- package/dist/storage/FileStorageAdapter.js.map +1 -0
- package/dist/terminal/WrappedShell.d.ts +24 -0
- package/dist/terminal/WrappedShell.d.ts.map +1 -0
- package/dist/terminal/WrappedShell.js +121 -0
- package/dist/terminal/WrappedShell.js.map +1 -0
- package/dist/terminal/activityDetector.d.ts +33 -0
- package/dist/terminal/activityDetector.d.ts.map +1 -0
- package/dist/terminal/activityDetector.js +158 -0
- package/dist/terminal/activityDetector.js.map +1 -0
- package/package.json +41 -7
- package/index.js +0 -2
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Session command - Start a wrapped shell session with tracking
|
|
4
|
+
*/
|
|
5
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
6
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
7
|
+
};
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.sessionCommand = void 0;
|
|
10
|
+
const commander_1 = require("commander");
|
|
11
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
12
|
+
const tracker_core_1 = require("@devclocked/tracker-core");
|
|
13
|
+
const FileStorageAdapter_1 = require("../storage/FileStorageAdapter");
|
|
14
|
+
const WrappedShell_1 = require("../terminal/WrappedShell");
|
|
15
|
+
const activityDetector_1 = require("../terminal/activityDetector");
|
|
16
|
+
const config_1 = require("../config");
|
|
17
|
+
const banner_1 = require("../branding/banner");
|
|
18
|
+
async function startSession() {
|
|
19
|
+
const storage = new FileStorageAdapter_1.FileStorageAdapter();
|
|
20
|
+
const client = new tracker_core_1.TrackerClient({
|
|
21
|
+
supabaseUrl: config_1.SUPABASE_URL,
|
|
22
|
+
supabaseAnonKey: config_1.SUPABASE_ANON_KEY,
|
|
23
|
+
source: 'cli',
|
|
24
|
+
clientId: `cli-${Date.now()}`,
|
|
25
|
+
debug: false,
|
|
26
|
+
}, storage);
|
|
27
|
+
// Check authentication
|
|
28
|
+
const isAuth = await client.isAuthenticated();
|
|
29
|
+
if (!isAuth) {
|
|
30
|
+
(0, banner_1.printError)('Not authenticated. Run: devclocked login');
|
|
31
|
+
client.destroy();
|
|
32
|
+
process.exit(1);
|
|
33
|
+
}
|
|
34
|
+
const authState = await client.getAuthState();
|
|
35
|
+
const cwd = process.cwd();
|
|
36
|
+
(0, banner_1.printSessionStart)();
|
|
37
|
+
(0, banner_1.printSuccess)(`Authenticated as ${chalk_1.default.cyan(authState?.email || 'unknown')}`);
|
|
38
|
+
(0, banner_1.printInfo)(`Working directory: ${chalk_1.default.gray(cwd)}`);
|
|
39
|
+
(0, banner_1.printInfo)('Type "exit" to end the session');
|
|
40
|
+
console.log();
|
|
41
|
+
let shell = null;
|
|
42
|
+
let detector = null;
|
|
43
|
+
let isEnding = false;
|
|
44
|
+
const cleanup = async (exitCode = 0) => {
|
|
45
|
+
if (isEnding)
|
|
46
|
+
return;
|
|
47
|
+
isEnding = true;
|
|
48
|
+
if (detector) {
|
|
49
|
+
detector.destroy();
|
|
50
|
+
detector = null;
|
|
51
|
+
}
|
|
52
|
+
if (shell) {
|
|
53
|
+
shell.destroy();
|
|
54
|
+
shell = null;
|
|
55
|
+
}
|
|
56
|
+
// Flush any pending ticks
|
|
57
|
+
try {
|
|
58
|
+
await client.flushQueue();
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
// Ignore flush errors on exit
|
|
62
|
+
}
|
|
63
|
+
client.destroy();
|
|
64
|
+
(0, banner_1.printSessionEnd)();
|
|
65
|
+
process.exit(exitCode);
|
|
66
|
+
};
|
|
67
|
+
// Handle process signals
|
|
68
|
+
process.on('SIGINT', () => cleanup(0));
|
|
69
|
+
process.on('SIGTERM', () => cleanup(0));
|
|
70
|
+
// Create activity detector with idle callback
|
|
71
|
+
const onIdle = () => {
|
|
72
|
+
(0, banner_1.printInfo)('Session idle - activity tracking paused');
|
|
73
|
+
};
|
|
74
|
+
shell = new WrappedShell_1.WrappedShell(cwd, (activityCwd) => {
|
|
75
|
+
if (detector) {
|
|
76
|
+
detector.onActivity(activityCwd);
|
|
77
|
+
}
|
|
78
|
+
}, (exitCode) => {
|
|
79
|
+
cleanup(exitCode);
|
|
80
|
+
});
|
|
81
|
+
detector = new activityDetector_1.ActivityDetector(client, shell.getShell(), onIdle);
|
|
82
|
+
// Initial tick to start session
|
|
83
|
+
detector.onActivity(cwd);
|
|
84
|
+
// Start the wrapped shell
|
|
85
|
+
shell.spawn();
|
|
86
|
+
}
|
|
87
|
+
exports.sessionCommand = new commander_1.Command('session')
|
|
88
|
+
.description('Start a tracked terminal session')
|
|
89
|
+
.action(startSession);
|
|
90
|
+
//# sourceMappingURL=session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/commands/session.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/commands/setup.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA0KpC,eAAO,MAAM,YAAY,SAET,CAAC"}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Setup command — one-shot install: login + register MCP server with Claude Code
|
|
4
|
+
*
|
|
5
|
+
* Usage: npx -y @devclocked/cli setup
|
|
6
|
+
*/
|
|
7
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
8
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
9
|
+
};
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.setupCommand = void 0;
|
|
12
|
+
const commander_1 = require("commander");
|
|
13
|
+
const readline_1 = require("readline");
|
|
14
|
+
const child_process_1 = require("child_process");
|
|
15
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
16
|
+
const tracker_core_1 = require("@devclocked/tracker-core");
|
|
17
|
+
const FileStorageAdapter_1 = require("../storage/FileStorageAdapter");
|
|
18
|
+
const config_1 = require("../config");
|
|
19
|
+
const banner_1 = require("../branding/banner");
|
|
20
|
+
const YELLOW = chalk_1.default.hex('#F8D74A');
|
|
21
|
+
const GRAY = chalk_1.default.gray;
|
|
22
|
+
async function promptApiKey() {
|
|
23
|
+
return new Promise((resolve) => {
|
|
24
|
+
const rl = (0, readline_1.createInterface)({
|
|
25
|
+
input: process.stdin,
|
|
26
|
+
output: process.stdout,
|
|
27
|
+
});
|
|
28
|
+
process.stdout.write(chalk_1.default.yellow('Enter your DevClocked API key: '));
|
|
29
|
+
let key = '';
|
|
30
|
+
const stdin = process.stdin;
|
|
31
|
+
const originalRawMode = stdin.isRaw;
|
|
32
|
+
if (stdin.isTTY) {
|
|
33
|
+
stdin.setRawMode(true);
|
|
34
|
+
stdin.resume();
|
|
35
|
+
stdin.setEncoding('utf8');
|
|
36
|
+
const onData = (char) => {
|
|
37
|
+
if (char === '\n' || char === '\r') {
|
|
38
|
+
stdin.setRawMode(originalRawMode ?? false);
|
|
39
|
+
stdin.removeListener('data', onData);
|
|
40
|
+
process.stdout.write('\n');
|
|
41
|
+
rl.close();
|
|
42
|
+
resolve(key);
|
|
43
|
+
}
|
|
44
|
+
else if (char === '\u0003') {
|
|
45
|
+
process.exit(0);
|
|
46
|
+
}
|
|
47
|
+
else if (char === '\u007F' || char === '\b') {
|
|
48
|
+
if (key.length > 0) {
|
|
49
|
+
key = key.slice(0, -1);
|
|
50
|
+
process.stdout.write('\b \b');
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
key += char;
|
|
55
|
+
process.stdout.write('*');
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
stdin.on('data', onData);
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
rl.question('', (answer) => {
|
|
62
|
+
rl.close();
|
|
63
|
+
resolve(answer);
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
function hasClaude() {
|
|
69
|
+
try {
|
|
70
|
+
(0, child_process_1.execSync)('which claude', { stdio: 'pipe' });
|
|
71
|
+
return true;
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
function registerMcpServer() {
|
|
78
|
+
try {
|
|
79
|
+
// Remove any existing (possibly broken) registration
|
|
80
|
+
try {
|
|
81
|
+
(0, child_process_1.execSync)('claude mcp remove devclocked 2>/dev/null', { stdio: 'pipe' });
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
// Fine if it doesn't exist
|
|
85
|
+
}
|
|
86
|
+
// Register globally with --scope user
|
|
87
|
+
(0, child_process_1.execSync)('claude mcp add --scope user devclocked -- npx -y devclocked mcp-server', { stdio: 'pipe' });
|
|
88
|
+
return true;
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
return false;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
async function setup() {
|
|
95
|
+
(0, banner_1.printBanner)();
|
|
96
|
+
console.log();
|
|
97
|
+
console.log(YELLOW('━'.repeat(50)));
|
|
98
|
+
console.log(YELLOW(' Setup — one command, fully installed'));
|
|
99
|
+
console.log(YELLOW('━'.repeat(50)));
|
|
100
|
+
console.log();
|
|
101
|
+
// Step 1: Auth
|
|
102
|
+
(0, banner_1.printInfo)('Step 1/2 — Authenticate');
|
|
103
|
+
(0, banner_1.printInfo)('Get your API key from: https://app.devclocked.com/settings');
|
|
104
|
+
console.log();
|
|
105
|
+
const apiKey = await promptApiKey();
|
|
106
|
+
if (!apiKey || !apiKey.startsWith('dck_')) {
|
|
107
|
+
(0, banner_1.printError)('Invalid API key format. Keys should start with "dck_"');
|
|
108
|
+
process.exit(1);
|
|
109
|
+
}
|
|
110
|
+
console.log();
|
|
111
|
+
(0, banner_1.printInfo)('Validating API key...');
|
|
112
|
+
const storage = new FileStorageAdapter_1.FileStorageAdapter();
|
|
113
|
+
const client = new tracker_core_1.TrackerClient({
|
|
114
|
+
supabaseUrl: config_1.SUPABASE_URL,
|
|
115
|
+
supabaseAnonKey: config_1.SUPABASE_ANON_KEY,
|
|
116
|
+
source: 'cli',
|
|
117
|
+
clientId: `cli-${Date.now()}`,
|
|
118
|
+
debug: false,
|
|
119
|
+
}, storage);
|
|
120
|
+
client.stopAutoProcessing();
|
|
121
|
+
try {
|
|
122
|
+
await client.authenticate(apiKey);
|
|
123
|
+
const authState = await client.getAuthState();
|
|
124
|
+
// Persist API key for MCP server
|
|
125
|
+
storage.set('api_key', apiKey);
|
|
126
|
+
(0, banner_1.printSuccess)(`Authenticated as ${chalk_1.default.cyan(authState?.email || 'unknown')}`);
|
|
127
|
+
client.destroy();
|
|
128
|
+
}
|
|
129
|
+
catch (error) {
|
|
130
|
+
(0, banner_1.printError)(`Authentication failed: ${error.message}`);
|
|
131
|
+
client.destroy();
|
|
132
|
+
process.exit(1);
|
|
133
|
+
}
|
|
134
|
+
console.log();
|
|
135
|
+
// Step 2: Register MCP server with Claude Code
|
|
136
|
+
(0, banner_1.printInfo)('Step 2/2 — Register MCP server with Claude Code');
|
|
137
|
+
if (!hasClaude()) {
|
|
138
|
+
(0, banner_1.printError)('Claude Code CLI not found.');
|
|
139
|
+
(0, banner_1.printInfo)('Install it first: https://docs.anthropic.com/en/docs/claude-code');
|
|
140
|
+
(0, banner_1.printInfo)('Then re-run: npx @devclocked/cli setup');
|
|
141
|
+
process.exit(1);
|
|
142
|
+
}
|
|
143
|
+
const registered = registerMcpServer();
|
|
144
|
+
if (registered) {
|
|
145
|
+
(0, banner_1.printSuccess)('MCP server registered with Claude Code');
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
(0, banner_1.printError)('Failed to register MCP server automatically.');
|
|
149
|
+
(0, banner_1.printInfo)('Run manually: claude mcp add --scope user devclocked -- npx -y @devclocked/cli@latest mcp-server');
|
|
150
|
+
}
|
|
151
|
+
// Done
|
|
152
|
+
console.log();
|
|
153
|
+
console.log(YELLOW('━'.repeat(50)));
|
|
154
|
+
(0, banner_1.printSuccess)(chalk_1.default.bold('DevClocked is installed!'));
|
|
155
|
+
console.log(YELLOW('━'.repeat(50)));
|
|
156
|
+
console.log();
|
|
157
|
+
(0, banner_1.printInfo)('Restart Claude Code to activate the MCP server.');
|
|
158
|
+
(0, banner_1.printInfo)(GRAY('Ask Claude: "how long have I been coding today?"'));
|
|
159
|
+
console.log();
|
|
160
|
+
}
|
|
161
|
+
exports.setupCommand = new commander_1.Command('setup')
|
|
162
|
+
.description('One-command install: authenticate + register MCP server')
|
|
163
|
+
.action(setup);
|
|
164
|
+
//# sourceMappingURL=setup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup.js","sourceRoot":"","sources":["../../src/commands/setup.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;;;;AAEH,yCAAoC;AACpC,uCAA2C;AAC3C,iDAAyC;AACzC,kDAA0B;AAC1B,2DAAyD;AACzD,sEAAmE;AACnE,sCAA4D;AAC5D,+CAAsF;AAEtF,MAAM,MAAM,GAAG,eAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;AACpC,MAAM,IAAI,GAAG,eAAK,CAAC,IAAI,CAAC;AAExB,KAAK,UAAU,YAAY;IACzB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,MAAM,EAAE,GAAG,IAAA,0BAAe,EAAC;YACzB,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,MAAM,EAAE,OAAO,CAAC,MAAM;SACvB,CAAC,CAAC;QAEH,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,eAAK,CAAC,MAAM,CAAC,iCAAiC,CAAC,CAAC,CAAC;QAEtE,IAAI,GAAG,GAAG,EAAE,CAAC;QACb,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;QAC5B,MAAM,eAAe,GAAG,KAAK,CAAC,KAAK,CAAC;QAEpC,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;YAChB,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;YACvB,KAAK,CAAC,MAAM,EAAE,CAAC;YACf,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;YAE1B,MAAM,MAAM,GAAG,CAAC,IAAY,EAAE,EAAE;gBAC9B,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;oBACnC,KAAK,CAAC,UAAU,CAAC,eAAe,IAAI,KAAK,CAAC,CAAC;oBAC3C,KAAK,CAAC,cAAc,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;oBACrC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;oBAC3B,EAAE,CAAC,KAAK,EAAE,CAAC;oBACX,OAAO,CAAC,GAAG,CAAC,CAAC;gBACf,CAAC;qBAAM,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;oBAC7B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;gBAClB,CAAC;qBAAM,IAAI,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;oBAC9C,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;wBACnB,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;wBACvB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;oBAChC,CAAC;gBACH,CAAC;qBAAM,CAAC;oBACN,GAAG,IAAI,IAAI,CAAC;oBACZ,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBAC5B,CAAC;YACH,CAAC,CAAC;YAEF,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC3B,CAAC;aAAM,CAAC;YACN,EAAE,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC,MAAM,EAAE,EAAE;gBACzB,EAAE,CAAC,KAAK,EAAE,CAAC;gBACX,OAAO,CAAC,MAAM,CAAC,CAAC;YAClB,CAAC,CAAC,CAAC;QACL,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,SAAS;IAChB,IAAI,CAAC;QACH,IAAA,wBAAQ,EAAC,cAAc,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;QAC5C,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,SAAS,iBAAiB;IACxB,IAAI,CAAC;QACH,qDAAqD;QACrD,IAAI,CAAC;YACH,IAAA,wBAAQ,EAAC,0CAA0C,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;QAC1E,CAAC;QAAC,MAAM,CAAC;YACP,2BAA2B;QAC7B,CAAC;QAED,sCAAsC;QACtC,IAAA,wBAAQ,EACN,wEAAwE,EACxE,EAAE,KAAK,EAAE,MAAM,EAAE,CAClB,CAAC;QACF,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,KAAK,UAAU,KAAK;IAClB,IAAA,oBAAW,GAAE,CAAC;IACd,OAAO,CAAC,GAAG,EAAE,CAAC;IACd,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IACpC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,wCAAwC,CAAC,CAAC,CAAC;IAC9D,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IACpC,OAAO,CAAC,GAAG,EAAE,CAAC;IAEd,eAAe;IACf,IAAA,kBAAS,EAAC,yBAAyB,CAAC,CAAC;IACrC,IAAA,kBAAS,EAAC,4DAA4D,CAAC,CAAC;IACxE,OAAO,CAAC,GAAG,EAAE,CAAC;IAEd,MAAM,MAAM,GAAG,MAAM,YAAY,EAAE,CAAC;IAEpC,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QAC1C,IAAA,mBAAU,EAAC,uDAAuD,CAAC,CAAC;QACpE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,OAAO,CAAC,GAAG,EAAE,CAAC;IACd,IAAA,kBAAS,EAAC,uBAAuB,CAAC,CAAC;IAEnC,MAAM,OAAO,GAAG,IAAI,uCAAkB,EAAE,CAAC;IACzC,MAAM,MAAM,GAAG,IAAI,4BAAa,CAAC;QAC/B,WAAW,EAAE,qBAAY;QACzB,eAAe,EAAE,0BAAiB;QAClC,MAAM,EAAE,KAAK;QACb,QAAQ,EAAE,OAAO,IAAI,CAAC,GAAG,EAAE,EAAE;QAC7B,KAAK,EAAE,KAAK;KACb,EAAE,OAAO,CAAC,CAAC;IAEZ,MAAM,CAAC,kBAAkB,EAAE,CAAC;IAE5B,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;QAClC,MAAM,SAAS,GAAG,MAAM,MAAM,CAAC,YAAY,EAAE,CAAC;QAE9C,iCAAiC;QACjC,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;QAE/B,IAAA,qBAAY,EAAC,oBAAoB,eAAK,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,IAAI,SAAS,CAAC,EAAE,CAAC,CAAC;QAC9E,MAAM,CAAC,OAAO,EAAE,CAAC;IACnB,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QACpB,IAAA,mBAAU,EAAC,0BAA0B,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QACtD,MAAM,CAAC,OAAO,EAAE,CAAC;QACjB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,OAAO,CAAC,GAAG,EAAE,CAAC;IAEd,+CAA+C;IAC/C,IAAA,kBAAS,EAAC,iDAAiD,CAAC,CAAC;IAE7D,IAAI,CAAC,SAAS,EAAE,EAAE,CAAC;QACjB,IAAA,mBAAU,EAAC,4BAA4B,CAAC,CAAC;QACzC,IAAA,kBAAS,EAAC,kEAAkE,CAAC,CAAC;QAC9E,IAAA,kBAAS,EAAC,wCAAwC,CAAC,CAAC;QACpD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,UAAU,GAAG,iBAAiB,EAAE,CAAC;IAEvC,IAAI,UAAU,EAAE,CAAC;QACf,IAAA,qBAAY,EAAC,wCAAwC,CAAC,CAAC;IACzD,CAAC;SAAM,CAAC;QACN,IAAA,mBAAU,EAAC,8CAA8C,CAAC,CAAC;QAC3D,IAAA,kBAAS,EAAC,kGAAkG,CAAC,CAAC;IAChH,CAAC;IAED,OAAO;IACP,OAAO,CAAC,GAAG,EAAE,CAAC;IACd,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IACpC,IAAA,qBAAY,EAAC,eAAK,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC,CAAC;IACrD,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IACpC,OAAO,CAAC,GAAG,EAAE,CAAC;IACd,IAAA,kBAAS,EAAC,iDAAiD,CAAC,CAAC;IAC7D,IAAA,kBAAS,EAAC,IAAI,CAAC,kDAAkD,CAAC,CAAC,CAAC;IACpE,OAAO,CAAC,GAAG,EAAE,CAAC;AAChB,CAAC;AAEY,QAAA,YAAY,GAAG,IAAI,mBAAO,CAAC,OAAO,CAAC;KAC7C,WAAW,CAAC,yDAAyD,CAAC;KACtE,MAAM,CAAC,KAAK,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA0EpC,eAAO,MAAM,aAAa,SAEL,CAAC"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Status command - Show current tracking state
|
|
4
|
+
*/
|
|
5
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
6
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
7
|
+
};
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.statusCommand = void 0;
|
|
10
|
+
const commander_1 = require("commander");
|
|
11
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
12
|
+
const tracker_core_1 = require("@devclocked/tracker-core");
|
|
13
|
+
const FileStorageAdapter_1 = require("../storage/FileStorageAdapter");
|
|
14
|
+
const config_1 = require("../config");
|
|
15
|
+
const banner_1 = require("../branding/banner");
|
|
16
|
+
async function showStatus() {
|
|
17
|
+
const storage = new FileStorageAdapter_1.FileStorageAdapter();
|
|
18
|
+
const client = new tracker_core_1.TrackerClient({
|
|
19
|
+
supabaseUrl: config_1.SUPABASE_URL,
|
|
20
|
+
supabaseAnonKey: config_1.SUPABASE_ANON_KEY,
|
|
21
|
+
source: 'cli',
|
|
22
|
+
clientId: `cli-${Date.now()}`,
|
|
23
|
+
debug: false,
|
|
24
|
+
}, storage);
|
|
25
|
+
// Stop auto-processing for CLI commands
|
|
26
|
+
client.stopAutoProcessing();
|
|
27
|
+
(0, banner_1.printHeader)('Status');
|
|
28
|
+
// Auth status
|
|
29
|
+
const isAuth = await client.isAuthenticated();
|
|
30
|
+
if (isAuth) {
|
|
31
|
+
const authState = await client.getAuthState();
|
|
32
|
+
(0, banner_1.printStatus)('Authenticated', authState?.email || 'unknown', true);
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
(0, banner_1.printStatus)('Authenticated', 'No', false);
|
|
36
|
+
(0, banner_1.printInfo)('Run: devclocked login');
|
|
37
|
+
client.destroy();
|
|
38
|
+
process.exit(0);
|
|
39
|
+
}
|
|
40
|
+
// Session status
|
|
41
|
+
try {
|
|
42
|
+
const session = await client.getActiveSessionFromBackend();
|
|
43
|
+
if (session && session.is_active) {
|
|
44
|
+
(0, banner_1.printStatus)('Active session', 'Yes', true);
|
|
45
|
+
(0, banner_1.printInfo)(` Source: ${chalk_1.default.cyan(session.source)}`);
|
|
46
|
+
(0, banner_1.printInfo)(` Started: ${chalk_1.default.gray((0, banner_1.formatTimeAgo)(session.started_at))}`);
|
|
47
|
+
if (session.last_tick_at) {
|
|
48
|
+
(0, banner_1.printInfo)(` Last tick: ${chalk_1.default.gray((0, banner_1.formatTimeAgo)(session.last_tick_at))}`);
|
|
49
|
+
}
|
|
50
|
+
(0, banner_1.printInfo)(` Tick count: ${chalk_1.default.cyan(String(session.tick_count || 0))}`);
|
|
51
|
+
if (session.repo_url) {
|
|
52
|
+
(0, banner_1.printInfo)(` Repository: ${chalk_1.default.cyan(session.repo_url)}`);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
(0, banner_1.printStatus)('Active session', 'No', false);
|
|
57
|
+
(0, banner_1.printInfo)('Start a session with: devclocked session');
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
(0, banner_1.printStatus)('Active session', 'Unknown', false);
|
|
62
|
+
}
|
|
63
|
+
// Queue status
|
|
64
|
+
try {
|
|
65
|
+
const queueStats = await client.getQueueStats();
|
|
66
|
+
(0, banner_1.printInfo)(` Queue: ${chalk_1.default.cyan(String(queueStats.totalItems))} pending`);
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
// Ignore queue errors
|
|
70
|
+
}
|
|
71
|
+
console.log();
|
|
72
|
+
client.destroy();
|
|
73
|
+
process.exit(0);
|
|
74
|
+
}
|
|
75
|
+
exports.statusCommand = new commander_1.Command('status')
|
|
76
|
+
.description('Show current tracking status')
|
|
77
|
+
.action(showStatus);
|
|
78
|
+
//# sourceMappingURL=status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"summary.d.ts","sourceRoot":"","sources":["../../src/commands/summary.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAsCpC,eAAO,MAAM,cAAc,SAIL,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Summary command — Visual dashboard of today's coding activity
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.summaryCommand = void 0;
|
|
7
|
+
const commander_1 = require("commander");
|
|
8
|
+
const banner_1 = require("../branding/banner");
|
|
9
|
+
const dashboard_1 = require("../branding/dashboard");
|
|
10
|
+
const auth_1 = require("../auth");
|
|
11
|
+
async function showSummary(options) {
|
|
12
|
+
const client = await (0, auth_1.createAuthenticatedClient)();
|
|
13
|
+
if (!client) {
|
|
14
|
+
(0, banner_1.printHeader)('Summary');
|
|
15
|
+
(0, banner_1.printError)('Not authenticated');
|
|
16
|
+
(0, banner_1.printInfo)('Run: devclocked login');
|
|
17
|
+
process.exit(1);
|
|
18
|
+
}
|
|
19
|
+
const tz = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
20
|
+
const data = await client.getTodayActivity({ date: options.date, tz });
|
|
21
|
+
if (!data) {
|
|
22
|
+
(0, banner_1.printHeader)('Summary');
|
|
23
|
+
(0, banner_1.printError)('Failed to fetch activity data');
|
|
24
|
+
client.destroy();
|
|
25
|
+
process.exit(1);
|
|
26
|
+
}
|
|
27
|
+
if (!process.stdout.isTTY) {
|
|
28
|
+
// Non-TTY (piped, captured, or non-interactive) — chalk-free visual box
|
|
29
|
+
console.log(options.full ? (0, dashboard_1.buildPlainVisualFull)(data) : (0, dashboard_1.buildPlainVisualSummary)(data));
|
|
30
|
+
}
|
|
31
|
+
else if (options.full) {
|
|
32
|
+
(0, dashboard_1.renderFullDashboard)(data);
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
(0, dashboard_1.renderCompactSummary)(data);
|
|
36
|
+
}
|
|
37
|
+
client.destroy();
|
|
38
|
+
process.exit(0);
|
|
39
|
+
}
|
|
40
|
+
exports.summaryCommand = new commander_1.Command('summary')
|
|
41
|
+
.description('Show today\'s coding activity dashboard')
|
|
42
|
+
.option('-d, --date <date>', 'Date in YYYY-MM-DD format (default: today)')
|
|
43
|
+
.option('-f, --full', 'Show full dashboard with all repos and progress bars')
|
|
44
|
+
.action(showSummary);
|
|
45
|
+
//# sourceMappingURL=summary.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"summary.js","sourceRoot":"","sources":["../../src/commands/summary.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAEH,yCAAoC;AACpC,+CAAwE;AACxE,qDAAiI;AACjI,kCAAoD;AAEpD,KAAK,UAAU,WAAW,CAAC,OAA0C;IACnE,MAAM,MAAM,GAAG,MAAM,IAAA,gCAAyB,GAAE,CAAC;IAEjD,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,IAAA,oBAAW,EAAC,SAAS,CAAC,CAAC;QACvB,IAAA,mBAAU,EAAC,mBAAmB,CAAC,CAAC;QAChC,IAAA,kBAAS,EAAC,uBAAuB,CAAC,CAAC;QACnC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,EAAE,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC,eAAe,EAAE,CAAC,QAAQ,CAAC;IAC5D,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,gBAAgB,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;IAEvE,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,IAAA,oBAAW,EAAC,SAAS,CAAC,CAAC;QACvB,IAAA,mBAAU,EAAC,+BAA+B,CAAC,CAAC;QAC5C,MAAM,CAAC,OAAO,EAAE,CAAC;QACjB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QAC1B,wEAAwE;QACxE,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAA,gCAAoB,EAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAA,mCAAuB,EAAC,IAAI,CAAC,CAAC,CAAC;IACzF,CAAC;SAAM,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QACxB,IAAA,+BAAmB,EAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;SAAM,CAAC;QACN,IAAA,gCAAoB,EAAC,IAAI,CAAC,CAAC;IAC7B,CAAC;IAED,MAAM,CAAC,OAAO,EAAE,CAAC;IACjB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAEY,QAAA,cAAc,GAAG,IAAI,mBAAO,CAAC,SAAS,CAAC;KACjD,WAAW,CAAC,yCAAyC,CAAC;KACtD,MAAM,CAAC,mBAAmB,EAAE,4CAA4C,CAAC;KACzE,MAAM,CAAC,YAAY,EAAE,sDAAsD,CAAC;KAC5E,MAAM,CAAC,WAAW,CAAC,CAAC"}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI Configuration Constants
|
|
3
|
+
*/
|
|
4
|
+
export declare const SUPABASE_URL = "https://haqfgkkmeglyrulmpist.supabase.co";
|
|
5
|
+
export declare const SUPABASE_ANON_KEY = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImhhcWZna2ttZWdseXJ1bG1waXN0Iiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTIwMDYyODcsImV4cCI6MjA2NzU4MjI4N30.fTonLdDRqqtV44tBcl0Z7ryvaSD5Gczy-OTkzHUw0o4";
|
|
6
|
+
export declare const CONFIG_DIR: string;
|
|
7
|
+
export declare const CONFIG_FILE: string;
|
|
8
|
+
export declare const REUSE_ACTIVE_WITHIN_MS = 120000;
|
|
9
|
+
export declare const END_SESSION_DEBOUNCE_MS = 60000;
|
|
10
|
+
export declare const IDLE_TIMEOUT_MS: number;
|
|
11
|
+
export declare const TICK_INTERVAL_MS = 30000;
|
|
12
|
+
export declare const CLI_VERSION = "2.0.0";
|
|
13
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,eAAO,MAAM,YAAY,6CAA6C,CAAC;AACvE,eAAO,MAAM,iBAAiB,qNAAqN,CAAC;AAGpP,eAAO,MAAM,UAAU,QAA2C,CAAC;AACnE,eAAO,MAAM,WAAW,QAA+B,CAAC;AAGxD,eAAO,MAAM,sBAAsB,SAAU,CAAC;AAC9C,eAAO,MAAM,uBAAuB,QAAS,CAAC;AAC9C,eAAO,MAAM,eAAe,QAAiB,CAAC;AAC9C,eAAO,MAAM,gBAAgB,QAAS,CAAC;AAGvC,eAAO,MAAM,WAAW,UAAU,CAAC"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* CLI Configuration Constants
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.CLI_VERSION = exports.TICK_INTERVAL_MS = exports.IDLE_TIMEOUT_MS = exports.END_SESSION_DEBOUNCE_MS = exports.REUSE_ACTIVE_WITHIN_MS = exports.CONFIG_FILE = exports.CONFIG_DIR = exports.SUPABASE_ANON_KEY = exports.SUPABASE_URL = void 0;
|
|
7
|
+
const os_1 = require("os");
|
|
8
|
+
const path_1 = require("path");
|
|
9
|
+
// Supabase configuration (same as other trackers)
|
|
10
|
+
exports.SUPABASE_URL = 'https://haqfgkkmeglyrulmpist.supabase.co';
|
|
11
|
+
exports.SUPABASE_ANON_KEY = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImhhcWZna2ttZWdseXJ1bG1waXN0Iiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTIwMDYyODcsImV4cCI6MjA2NzU4MjI4N30.fTonLdDRqqtV44tBcl0Z7ryvaSD5Gczy-OTkzHUw0o4';
|
|
12
|
+
// Storage paths
|
|
13
|
+
exports.CONFIG_DIR = (0, path_1.join)((0, os_1.homedir)(), '.config', 'devclocked');
|
|
14
|
+
exports.CONFIG_FILE = (0, path_1.join)(exports.CONFIG_DIR, 'cli.json');
|
|
15
|
+
// Session constants (aligned with tracker-core)
|
|
16
|
+
exports.REUSE_ACTIVE_WITHIN_MS = 120000; // 2 minutes
|
|
17
|
+
exports.END_SESSION_DEBOUNCE_MS = 60000; // 1 minute
|
|
18
|
+
exports.IDLE_TIMEOUT_MS = 15 * 60 * 1000; // 15 minutes
|
|
19
|
+
exports.TICK_INTERVAL_MS = 30000; // 30 seconds minimum between ticks
|
|
20
|
+
// CLI version
|
|
21
|
+
exports.CLI_VERSION = '2.0.0';
|
|
22
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAEH,2BAA6B;AAC7B,+BAA4B;AAE5B,kDAAkD;AACrC,QAAA,YAAY,GAAG,0CAA0C,CAAC;AAC1D,QAAA,iBAAiB,GAAG,kNAAkN,CAAC;AAEpP,gBAAgB;AACH,QAAA,UAAU,GAAG,IAAA,WAAI,EAAC,IAAA,YAAO,GAAE,EAAE,SAAS,EAAE,YAAY,CAAC,CAAC;AACtD,QAAA,WAAW,GAAG,IAAA,WAAI,EAAC,kBAAU,EAAE,UAAU,CAAC,CAAC;AAExD,gDAAgD;AACnC,QAAA,sBAAsB,GAAG,MAAO,CAAC,CAAC,YAAY;AAC9C,QAAA,uBAAuB,GAAG,KAAM,CAAC,CAAC,WAAW;AAC7C,QAAA,eAAe,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,aAAa;AAC/C,QAAA,gBAAgB,GAAG,KAAM,CAAC,CAAC,mCAAmC;AAE3E,cAAc;AACD,QAAA,WAAW,GAAG,OAAO,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* DevClocked CLI - Terminal time tracking for developers
|
|
4
|
+
*
|
|
5
|
+
* Privacy guarantees:
|
|
6
|
+
* - Commands are NOT logged
|
|
7
|
+
* - Arguments are NOT logged
|
|
8
|
+
* - Output is NOT stored
|
|
9
|
+
* - Environment variables are NOT captured
|
|
10
|
+
* - Only tracked: timestamps, cwd, repo context
|
|
11
|
+
*/
|
|
12
|
+
export {};
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;;;;;GASG"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
/**
|
|
4
|
+
* DevClocked CLI - Terminal time tracking for developers
|
|
5
|
+
*
|
|
6
|
+
* Privacy guarantees:
|
|
7
|
+
* - Commands are NOT logged
|
|
8
|
+
* - Arguments are NOT logged
|
|
9
|
+
* - Output is NOT stored
|
|
10
|
+
* - Environment variables are NOT captured
|
|
11
|
+
* - Only tracked: timestamps, cwd, repo context
|
|
12
|
+
*/
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
const commander_1 = require("commander");
|
|
15
|
+
const login_1 = require("./commands/login");
|
|
16
|
+
const logout_1 = require("./commands/logout");
|
|
17
|
+
const session_1 = require("./commands/session");
|
|
18
|
+
const status_1 = require("./commands/status");
|
|
19
|
+
const flush_1 = require("./commands/flush");
|
|
20
|
+
const summary_1 = require("./commands/summary");
|
|
21
|
+
const mcp_server_1 = require("./commands/mcp-server");
|
|
22
|
+
const mcp_health_1 = require("./commands/mcp-health");
|
|
23
|
+
const setup_1 = require("./commands/setup");
|
|
24
|
+
const program = new commander_1.Command();
|
|
25
|
+
program
|
|
26
|
+
.name('devclocked')
|
|
27
|
+
.description('DevClocked CLI - Terminal time tracking for developers')
|
|
28
|
+
.version('2.0.0');
|
|
29
|
+
program.addCommand(login_1.loginCommand);
|
|
30
|
+
program.addCommand(logout_1.logoutCommand);
|
|
31
|
+
program.addCommand(session_1.sessionCommand);
|
|
32
|
+
program.addCommand(status_1.statusCommand);
|
|
33
|
+
program.addCommand(flush_1.flushCommand);
|
|
34
|
+
program.addCommand(summary_1.summaryCommand);
|
|
35
|
+
program.addCommand(mcp_server_1.mcpServerCommand);
|
|
36
|
+
program.addCommand(mcp_server_1.mcpListToolsCommand);
|
|
37
|
+
program.addCommand(mcp_health_1.mcpHealthCommand);
|
|
38
|
+
program.addCommand(setup_1.setupCommand);
|
|
39
|
+
program.parse();
|
|
40
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;AACA;;;;;;;;;GASG;;AAEH,yCAAoC;AACpC,4CAAgD;AAChD,8CAAkD;AAClD,gDAAoD;AACpD,8CAAkD;AAClD,4CAAgD;AAChD,gDAAoD;AACpD,sDAA8E;AAC9E,sDAAyD;AACzD,4CAAgD;AAEhD,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,YAAY,CAAC;KAClB,WAAW,CAAC,wDAAwD,CAAC;KACrE,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,OAAO,CAAC,UAAU,CAAC,oBAAY,CAAC,CAAC;AACjC,OAAO,CAAC,UAAU,CAAC,sBAAa,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,wBAAc,CAAC,CAAC;AACnC,OAAO,CAAC,UAAU,CAAC,sBAAa,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,oBAAY,CAAC,CAAC;AACjC,OAAO,CAAC,UAAU,CAAC,wBAAc,CAAC,CAAC;AACnC,OAAO,CAAC,UAAU,CAAC,6BAAgB,CAAC,CAAC;AACrC,OAAO,CAAC,UAAU,CAAC,gCAAmB,CAAC,CAAC;AACxC,OAAO,CAAC,UAAU,CAAC,6BAAgB,CAAC,CAAC;AACrC,OAAO,CAAC,UAAU,CAAC,oBAAY,CAAC,CAAC;AAEjC,OAAO,CAAC,KAAK,EAAE,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared utilities for MCP server and MCP health commands.
|
|
3
|
+
*/
|
|
4
|
+
export interface McpAuth {
|
|
5
|
+
apiKey: string;
|
|
6
|
+
userId: string;
|
|
7
|
+
email: string;
|
|
8
|
+
}
|
|
9
|
+
export declare function getAuth(): McpAuth;
|
|
10
|
+
export declare function callEdgeFunction(auth: McpAuth, name: string, options?: {
|
|
11
|
+
method?: 'GET' | 'POST';
|
|
12
|
+
body?: Record<string, unknown>;
|
|
13
|
+
queryParams?: Record<string, string>;
|
|
14
|
+
}): Promise<unknown>;
|
|
15
|
+
//# sourceMappingURL=mcp-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-utils.d.ts","sourceRoot":"","sources":["../src/mcp-utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAOH,MAAM,WAAW,OAAO;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,OAAO,IAAI,OAAO,CA4BjC;AAED,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,OAAO,EACb,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE;IACR,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACtC,GACA,OAAO,CAAC,OAAO,CAAC,CA2BlB"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Shared utilities for MCP server and MCP health commands.
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.getAuth = getAuth;
|
|
7
|
+
exports.callEdgeFunction = callEdgeFunction;
|
|
8
|
+
const fs_1 = require("fs");
|
|
9
|
+
const path_1 = require("path");
|
|
10
|
+
const os_1 = require("os");
|
|
11
|
+
const config_1 = require("./config");
|
|
12
|
+
function getAuth() {
|
|
13
|
+
const configFile = (0, path_1.join)((0, os_1.homedir)(), '.config', 'devclocked', 'cli.json');
|
|
14
|
+
let raw;
|
|
15
|
+
try {
|
|
16
|
+
raw = (0, fs_1.readFileSync)(configFile, 'utf-8');
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
throw new Error(`Not authenticated. Run "devclocked login" first.\nExpected config at: ${configFile}`);
|
|
20
|
+
}
|
|
21
|
+
const config = JSON.parse(raw);
|
|
22
|
+
// New format: api_key + auth_metadata stored as separate keys
|
|
23
|
+
if (config.api_key) {
|
|
24
|
+
const metadata = config.auth_metadata ? JSON.parse(config.auth_metadata) : {};
|
|
25
|
+
return { apiKey: config.api_key, userId: metadata.userId || '', email: metadata.email || '' };
|
|
26
|
+
}
|
|
27
|
+
// Legacy format: auth_state with embedded apiKey
|
|
28
|
+
if (config.auth_state) {
|
|
29
|
+
const auth = JSON.parse(config.auth_state);
|
|
30
|
+
if (auth.apiKey) {
|
|
31
|
+
return { apiKey: auth.apiKey, userId: auth.userId, email: auth.email };
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
throw new Error('No auth found in config. Run "devclocked login" to authenticate.');
|
|
35
|
+
}
|
|
36
|
+
async function callEdgeFunction(auth, name, options) {
|
|
37
|
+
const method = options?.method ?? 'POST';
|
|
38
|
+
let url = `${config_1.SUPABASE_URL}/functions/v1/${name}`;
|
|
39
|
+
if (options?.queryParams) {
|
|
40
|
+
const params = new URLSearchParams(options.queryParams);
|
|
41
|
+
url += `?${params.toString()}`;
|
|
42
|
+
}
|
|
43
|
+
const res = await fetch(url, {
|
|
44
|
+
method,
|
|
45
|
+
headers: {
|
|
46
|
+
'Content-Type': 'application/json',
|
|
47
|
+
'Authorization': `Bearer ${config_1.SUPABASE_ANON_KEY}`,
|
|
48
|
+
'apikey': config_1.SUPABASE_ANON_KEY,
|
|
49
|
+
'x-devclocked-key': auth.apiKey,
|
|
50
|
+
'x-devclocked-source': 'mcp',
|
|
51
|
+
},
|
|
52
|
+
body: method === 'POST' ? JSON.stringify(options?.body ?? {}) : undefined,
|
|
53
|
+
});
|
|
54
|
+
if (!res.ok) {
|
|
55
|
+
const text = await res.text();
|
|
56
|
+
throw new Error(`Edge function ${name} failed: ${res.status} ${text}`);
|
|
57
|
+
}
|
|
58
|
+
return res.json();
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=mcp-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-utils.js","sourceRoot":"","sources":["../src/mcp-utils.ts"],"names":[],"mappings":";AAAA;;GAEG;;AAaH,0BA4BC;AAED,4CAmCC;AA5ED,2BAAkC;AAClC,+BAA4B;AAC5B,2BAA6B;AAC7B,qCAA2D;AAQ3D,SAAgB,OAAO;IACrB,MAAM,UAAU,GAAG,IAAA,WAAI,EAAC,IAAA,YAAO,GAAE,EAAE,SAAS,EAAE,YAAY,EAAE,UAAU,CAAC,CAAC;IACxE,IAAI,GAAW,CAAC;IAChB,IAAI,CAAC;QACH,GAAG,GAAG,IAAA,iBAAY,EAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IAC1C,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CACb,yEAAyE,UAAU,EAAE,CACtF,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAE/B,8DAA8D;IAC9D,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACnB,MAAM,QAAQ,GAAG,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9E,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,IAAI,EAAE,EAAE,KAAK,EAAE,QAAQ,CAAC,KAAK,IAAI,EAAE,EAAE,CAAC;IAChG,CAAC;IAED,iDAAiD;IACjD,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;QACtB,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QAC3C,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC;QACzE,CAAC;IACH,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,kEAAkE,CAAC,CAAC;AACtF,CAAC;AAEM,KAAK,UAAU,gBAAgB,CACpC,IAAa,EACb,IAAY,EACZ,OAIC;IAED,MAAM,MAAM,GAAG,OAAO,EAAE,MAAM,IAAI,MAAM,CAAC;IAEzC,IAAI,GAAG,GAAG,GAAG,qBAAY,iBAAiB,IAAI,EAAE,CAAC;IACjD,IAAI,OAAO,EAAE,WAAW,EAAE,CAAC;QACzB,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QACxD,GAAG,IAAI,IAAI,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC;IACjC,CAAC;IAED,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;QAC3B,MAAM;QACN,OAAO,EAAE;YACP,cAAc,EAAE,kBAAkB;YAClC,eAAe,EAAE,UAAU,0BAAiB,EAAE;YAC9C,QAAQ,EAAE,0BAAiB;YAC3B,kBAAkB,EAAE,IAAI,CAAC,MAAM;YAC/B,qBAAqB,EAAE,KAAK;SAC7B;QACD,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS;KAC1E,CAAC,CAAC;IAEH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;QAC9B,MAAM,IAAI,KAAK,CAAC,iBAAiB,IAAI,YAAY,GAAG,CAAC,MAAM,IAAI,IAAI,EAAE,CAAC,CAAC;IACzE,CAAC;IAED,OAAO,GAAG,CAAC,IAAI,EAAE,CAAC;AACpB,CAAC"}
|