@devclocked/cli 1.0.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.
Files changed (46) hide show
  1. package/README.md +78 -0
  2. package/dist/branding/banner.d.ts +16 -0
  3. package/dist/branding/banner.d.ts.map +1 -0
  4. package/dist/branding/banner.js +109 -0
  5. package/dist/branding/banner.js.map +1 -0
  6. package/dist/commands/flush.d.ts +6 -0
  7. package/dist/commands/flush.d.ts.map +1 -0
  8. package/dist/commands/flush.js +54 -0
  9. package/dist/commands/flush.js.map +1 -0
  10. package/dist/commands/login.d.ts +6 -0
  11. package/dist/commands/login.d.ts.map +1 -0
  12. package/dist/commands/login.js +106 -0
  13. package/dist/commands/login.js.map +1 -0
  14. package/dist/commands/logout.d.ts +6 -0
  15. package/dist/commands/logout.d.ts.map +1 -0
  16. package/dist/commands/logout.js +38 -0
  17. package/dist/commands/logout.js.map +1 -0
  18. package/dist/commands/session.d.ts +6 -0
  19. package/dist/commands/session.d.ts.map +1 -0
  20. package/dist/commands/session.js +90 -0
  21. package/dist/commands/session.js.map +1 -0
  22. package/dist/commands/status.d.ts +6 -0
  23. package/dist/commands/status.d.ts.map +1 -0
  24. package/dist/commands/status.js +78 -0
  25. package/dist/commands/status.js.map +1 -0
  26. package/dist/config.d.ts +13 -0
  27. package/dist/config.d.ts.map +1 -0
  28. package/dist/config.js +22 -0
  29. package/dist/config.js.map +1 -0
  30. package/dist/index.d.ts +13 -0
  31. package/dist/index.d.ts.map +1 -0
  32. package/dist/index.js +31 -0
  33. package/dist/index.js.map +1 -0
  34. package/dist/storage/FileStorageAdapter.d.ts +19 -0
  35. package/dist/storage/FileStorageAdapter.d.ts.map +1 -0
  36. package/dist/storage/FileStorageAdapter.js +80 -0
  37. package/dist/storage/FileStorageAdapter.js.map +1 -0
  38. package/dist/terminal/WrappedShell.d.ts +24 -0
  39. package/dist/terminal/WrappedShell.d.ts.map +1 -0
  40. package/dist/terminal/WrappedShell.js +121 -0
  41. package/dist/terminal/WrappedShell.js.map +1 -0
  42. package/dist/terminal/activityDetector.d.ts +33 -0
  43. package/dist/terminal/activityDetector.d.ts.map +1 -0
  44. package/dist/terminal/activityDetector.js +158 -0
  45. package/dist/terminal/activityDetector.js.map +1 -0
  46. package/package.json +52 -0
@@ -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,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 = "1.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 = '1.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"}
@@ -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,31 @@
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 program = new commander_1.Command();
21
+ program
22
+ .name('devclocked')
23
+ .description('DevClocked CLI - Terminal time tracking for developers')
24
+ .version('1.0.0');
25
+ program.addCommand(login_1.loginCommand);
26
+ program.addCommand(logout_1.logoutCommand);
27
+ program.addCommand(session_1.sessionCommand);
28
+ program.addCommand(status_1.statusCommand);
29
+ program.addCommand(flush_1.flushCommand);
30
+ program.parse();
31
+ //# 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;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;AAEjC,OAAO,CAAC,KAAK,EAAE,CAAC"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * File-based storage adapter for CLI
3
+ * Stores data in ~/.config/devclocked/cli.json
4
+ */
5
+ import { StorageAdapter } from '@devclocked/tracker-core';
6
+ export declare class FileStorageAdapter extends StorageAdapter {
7
+ private data;
8
+ private loaded;
9
+ constructor();
10
+ private ensureConfigDir;
11
+ private loadFromDisk;
12
+ private saveToDisk;
13
+ get(key: string): Promise<string | null>;
14
+ set(key: string, value: string): Promise<void>;
15
+ remove(key: string): Promise<void>;
16
+ clear(): Promise<void>;
17
+ keys(): Promise<string[]>;
18
+ }
19
+ //# sourceMappingURL=FileStorageAdapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FileStorageAdapter.d.ts","sourceRoot":"","sources":["../../src/storage/FileStorageAdapter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAS1D,qBAAa,kBAAmB,SAAQ,cAAc;IACpD,OAAO,CAAC,IAAI,CAAmB;IAC/B,OAAO,CAAC,MAAM,CAAS;;IAQvB,OAAO,CAAC,eAAe;IAMvB,OAAO,CAAC,YAAY;IAepB,OAAO,CAAC,UAAU;IAkBZ,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAKxC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAM9C,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAMlC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAKtB,IAAI,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;CAIhC"}
@@ -0,0 +1,80 @@
1
+ "use strict";
2
+ /**
3
+ * File-based storage adapter for CLI
4
+ * Stores data in ~/.config/devclocked/cli.json
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.FileStorageAdapter = void 0;
8
+ const tracker_core_1 = require("@devclocked/tracker-core");
9
+ const fs_1 = require("fs");
10
+ const path_1 = require("path");
11
+ const config_1 = require("../config");
12
+ class FileStorageAdapter extends tracker_core_1.StorageAdapter {
13
+ constructor() {
14
+ super();
15
+ this.data = {};
16
+ this.loaded = false;
17
+ this.ensureConfigDir();
18
+ this.loadFromDisk();
19
+ }
20
+ ensureConfigDir() {
21
+ if (!(0, fs_1.existsSync)(config_1.CONFIG_DIR)) {
22
+ (0, fs_1.mkdirSync)(config_1.CONFIG_DIR, { recursive: true, mode: 0o700 });
23
+ }
24
+ }
25
+ loadFromDisk() {
26
+ if (this.loaded)
27
+ return;
28
+ try {
29
+ if ((0, fs_1.existsSync)(config_1.CONFIG_FILE)) {
30
+ const content = (0, fs_1.readFileSync)(config_1.CONFIG_FILE, 'utf-8');
31
+ this.data = JSON.parse(content);
32
+ }
33
+ }
34
+ catch (error) {
35
+ // Start fresh if file is corrupted
36
+ this.data = {};
37
+ }
38
+ this.loaded = true;
39
+ }
40
+ saveToDisk() {
41
+ try {
42
+ const dir = (0, path_1.dirname)(config_1.CONFIG_FILE);
43
+ if (!(0, fs_1.existsSync)(dir)) {
44
+ (0, fs_1.mkdirSync)(dir, { recursive: true, mode: 0o700 });
45
+ }
46
+ (0, fs_1.writeFileSync)(config_1.CONFIG_FILE, JSON.stringify(this.data, null, 2), {
47
+ mode: 0o600, // User-only read/write
48
+ });
49
+ // Ensure permissions are correct
50
+ (0, fs_1.chmodSync)(config_1.CONFIG_FILE, 0o600);
51
+ }
52
+ catch (error) {
53
+ console.error('Failed to save config:', error);
54
+ }
55
+ }
56
+ async get(key) {
57
+ this.loadFromDisk();
58
+ return this.data[key] ?? null;
59
+ }
60
+ async set(key, value) {
61
+ this.loadFromDisk();
62
+ this.data[key] = value;
63
+ this.saveToDisk();
64
+ }
65
+ async remove(key) {
66
+ this.loadFromDisk();
67
+ delete this.data[key];
68
+ this.saveToDisk();
69
+ }
70
+ async clear() {
71
+ this.data = {};
72
+ this.saveToDisk();
73
+ }
74
+ async keys() {
75
+ this.loadFromDisk();
76
+ return Object.keys(this.data);
77
+ }
78
+ }
79
+ exports.FileStorageAdapter = FileStorageAdapter;
80
+ //# sourceMappingURL=FileStorageAdapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FileStorageAdapter.js","sourceRoot":"","sources":["../../src/storage/FileStorageAdapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Wrapped Shell - PTY wrapper for terminal activity detection
3
+ *
4
+ * Privacy guarantees:
5
+ * - Commands are NOT logged
6
+ * - Output is NOT stored
7
+ * - Only timestamps and cwd are tracked
8
+ */
9
+ export type ActivityCallback = (cwd: string) => void;
10
+ export type ExitCallback = (code: number) => void;
11
+ export declare class WrappedShell {
12
+ private ptyProcess;
13
+ private cwd;
14
+ private shell;
15
+ private activityCallback;
16
+ private exitCallback;
17
+ constructor(cwd: string, activityCallback: ActivityCallback, exitCallback: ExitCallback);
18
+ private detectShell;
19
+ getShell(): string;
20
+ spawn(): void;
21
+ private cleanup;
22
+ destroy(): void;
23
+ }
24
+ //# sourceMappingURL=WrappedShell.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WrappedShell.d.ts","sourceRoot":"","sources":["../../src/terminal/WrappedShell.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,MAAM,MAAM,gBAAgB,GAAG,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;AACrD,MAAM,MAAM,YAAY,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;AAElD,qBAAa,YAAY;IACvB,OAAO,CAAC,UAAU,CAAyB;IAC3C,OAAO,CAAC,GAAG,CAAS;IACpB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,gBAAgB,CAAmB;IAC3C,OAAO,CAAC,YAAY,CAAe;gBAGjC,GAAG,EAAE,MAAM,EACX,gBAAgB,EAAE,gBAAgB,EAClC,YAAY,EAAE,YAAY;IAQ5B,OAAO,CAAC,WAAW;IAWnB,QAAQ,IAAI,MAAM;IAIlB,KAAK,IAAI,IAAI;IAiDb,OAAO,CAAC,OAAO;IAOf,OAAO,IAAI,IAAI;CAOhB"}
@@ -0,0 +1,121 @@
1
+ "use strict";
2
+ /**
3
+ * Wrapped Shell - PTY wrapper for terminal activity detection
4
+ *
5
+ * Privacy guarantees:
6
+ * - Commands are NOT logged
7
+ * - Output is NOT stored
8
+ * - Only timestamps and cwd are tracked
9
+ */
10
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ var desc = Object.getOwnPropertyDescriptor(m, k);
13
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
14
+ desc = { enumerable: true, get: function() { return m[k]; } };
15
+ }
16
+ Object.defineProperty(o, k2, desc);
17
+ }) : (function(o, m, k, k2) {
18
+ if (k2 === undefined) k2 = k;
19
+ o[k2] = m[k];
20
+ }));
21
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
22
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
23
+ }) : function(o, v) {
24
+ o["default"] = v;
25
+ });
26
+ var __importStar = (this && this.__importStar) || (function () {
27
+ var ownKeys = function(o) {
28
+ ownKeys = Object.getOwnPropertyNames || function (o) {
29
+ var ar = [];
30
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
31
+ return ar;
32
+ };
33
+ return ownKeys(o);
34
+ };
35
+ return function (mod) {
36
+ if (mod && mod.__esModule) return mod;
37
+ var result = {};
38
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
39
+ __setModuleDefault(result, mod);
40
+ return result;
41
+ };
42
+ })();
43
+ Object.defineProperty(exports, "__esModule", { value: true });
44
+ exports.WrappedShell = void 0;
45
+ const pty = __importStar(require("node-pty"));
46
+ const os_1 = require("os");
47
+ class WrappedShell {
48
+ constructor(cwd, activityCallback, exitCallback) {
49
+ this.ptyProcess = null;
50
+ this.cwd = cwd;
51
+ this.activityCallback = activityCallback;
52
+ this.exitCallback = exitCallback;
53
+ this.shell = this.detectShell();
54
+ }
55
+ detectShell() {
56
+ const shellEnv = process.env.SHELL;
57
+ if (shellEnv)
58
+ return shellEnv;
59
+ if ((0, os_1.platform)() === 'win32') {
60
+ return process.env.COMSPEC || 'cmd.exe';
61
+ }
62
+ return '/bin/sh';
63
+ }
64
+ getShell() {
65
+ return this.shell;
66
+ }
67
+ spawn() {
68
+ const isWindows = (0, os_1.platform)() === 'win32';
69
+ this.ptyProcess = pty.spawn(this.shell, [], {
70
+ name: 'xterm-256color',
71
+ cols: process.stdout.columns || 80,
72
+ rows: process.stdout.rows || 24,
73
+ cwd: this.cwd,
74
+ env: process.env,
75
+ useConpty: isWindows,
76
+ });
77
+ // Pipe PTY output to stdout (transparent)
78
+ this.ptyProcess.onData((data) => {
79
+ process.stdout.write(data);
80
+ });
81
+ // Pipe stdin to PTY
82
+ if (process.stdin.isTTY) {
83
+ process.stdin.setRawMode(true);
84
+ }
85
+ process.stdin.resume();
86
+ process.stdin.setEncoding('utf8');
87
+ process.stdin.on('data', (data) => {
88
+ if (this.ptyProcess) {
89
+ this.ptyProcess.write(data.toString());
90
+ // Signal activity on input (NOT logging the content)
91
+ this.activityCallback(this.cwd);
92
+ }
93
+ });
94
+ // Handle terminal resize
95
+ process.stdout.on('resize', () => {
96
+ if (this.ptyProcess) {
97
+ this.ptyProcess.resize(process.stdout.columns || 80, process.stdout.rows || 24);
98
+ }
99
+ });
100
+ // Handle shell exit
101
+ this.ptyProcess.onExit(({ exitCode }) => {
102
+ this.cleanup();
103
+ this.exitCallback(exitCode);
104
+ });
105
+ }
106
+ cleanup() {
107
+ if (process.stdin.isTTY) {
108
+ process.stdin.setRawMode(false);
109
+ }
110
+ process.stdin.pause();
111
+ }
112
+ destroy() {
113
+ this.cleanup();
114
+ if (this.ptyProcess) {
115
+ this.ptyProcess.kill();
116
+ this.ptyProcess = null;
117
+ }
118
+ }
119
+ }
120
+ exports.WrappedShell = WrappedShell;
121
+ //# sourceMappingURL=WrappedShell.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WrappedShell.js","sourceRoot":"","sources":["../../src/terminal/WrappedShell.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Activity Detector - Debounces activity and detects git repo context
3
+ *
4
+ * Privacy guarantees:
5
+ * - Only tracks timestamps and cwd
6
+ * - No command or output logging
7
+ */
8
+ import { TrackerClient } from '@devclocked/tracker-core';
9
+ export interface RepoContext {
10
+ repoUrl?: string;
11
+ repoFullName?: string;
12
+ branch?: string;
13
+ }
14
+ export declare class ActivityDetector {
15
+ private lastTickAt;
16
+ private lastActivityAt;
17
+ private idleTimer;
18
+ private client;
19
+ private shell;
20
+ private onIdle;
21
+ private cachedRepo;
22
+ constructor(client: TrackerClient, shell: string, onIdle: () => void);
23
+ onActivity(cwd: string): void;
24
+ private resetIdleTimer;
25
+ private emitTick;
26
+ private detectGitRepo;
27
+ private findGitDir;
28
+ private normalizeRepoUrl;
29
+ private extractRepoFullName;
30
+ getLastActivityAt(): number;
31
+ destroy(): void;
32
+ }
33
+ //# sourceMappingURL=activityDetector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"activityDetector.d.ts","sourceRoot":"","sources":["../../src/terminal/activityDetector.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAMzD,MAAM,WAAW,WAAW;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,cAAc,CAAK;IAC3B,OAAO,CAAC,SAAS,CAA+B;IAChD,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,MAAM,CAAa;IAC3B,OAAO,CAAC,UAAU,CAAsD;gBAGtE,MAAM,EAAE,aAAa,EACrB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,IAAI;IAOpB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAgB7B,OAAO,CAAC,cAAc;YAUR,QAAQ;IActB,OAAO,CAAC,aAAa;IAsDrB,OAAO,CAAC,UAAU;IAclB,OAAO,CAAC,gBAAgB;IASxB,OAAO,CAAC,mBAAmB;IA2B3B,iBAAiB,IAAI,MAAM;IAI3B,OAAO,IAAI,IAAI;CAMhB"}
@@ -0,0 +1,158 @@
1
+ "use strict";
2
+ /**
3
+ * Activity Detector - Debounces activity and detects git repo context
4
+ *
5
+ * Privacy guarantees:
6
+ * - Only tracks timestamps and cwd
7
+ * - No command or output logging
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.ActivityDetector = void 0;
11
+ const child_process_1 = require("child_process");
12
+ const fs_1 = require("fs");
13
+ const path_1 = require("path");
14
+ const config_1 = require("../config");
15
+ class ActivityDetector {
16
+ constructor(client, shell, onIdle) {
17
+ this.lastTickAt = 0;
18
+ this.lastActivityAt = 0;
19
+ this.idleTimer = null;
20
+ this.cachedRepo = null;
21
+ this.client = client;
22
+ this.shell = shell;
23
+ this.onIdle = onIdle;
24
+ }
25
+ onActivity(cwd) {
26
+ const now = Date.now();
27
+ this.lastActivityAt = now;
28
+ // Reset idle timer
29
+ this.resetIdleTimer();
30
+ // Debounce ticks
31
+ if (now - this.lastTickAt < config_1.TICK_INTERVAL_MS) {
32
+ return;
33
+ }
34
+ this.lastTickAt = now;
35
+ this.emitTick(cwd);
36
+ }
37
+ resetIdleTimer() {
38
+ if (this.idleTimer) {
39
+ clearTimeout(this.idleTimer);
40
+ }
41
+ this.idleTimer = setTimeout(() => {
42
+ this.onIdle();
43
+ }, config_1.IDLE_TIMEOUT_MS);
44
+ }
45
+ async emitTick(cwd) {
46
+ const repoContext = this.detectGitRepo(cwd);
47
+ try {
48
+ await this.client.sendTick('terminal', 'window', {
49
+ repo_url: repoContext.repoUrl,
50
+ branch: repoContext.branch,
51
+ repository_full_name: repoContext.repoFullName,
52
+ });
53
+ }
54
+ catch (error) {
55
+ // Queue will retry
56
+ }
57
+ }
58
+ detectGitRepo(cwd) {
59
+ // Use cache if same cwd
60
+ if (this.cachedRepo && this.cachedRepo.cwd === cwd) {
61
+ return this.cachedRepo.context;
62
+ }
63
+ const context = {};
64
+ try {
65
+ // Find git root
66
+ const gitDir = this.findGitDir(cwd);
67
+ if (!gitDir) {
68
+ this.cachedRepo = { cwd, context };
69
+ return context;
70
+ }
71
+ // Get remote URL
72
+ try {
73
+ const remoteUrl = (0, child_process_1.execSync)('git config --get remote.origin.url', {
74
+ cwd,
75
+ encoding: 'utf-8',
76
+ stdio: ['pipe', 'pipe', 'pipe'],
77
+ }).trim();
78
+ if (remoteUrl) {
79
+ context.repoUrl = this.normalizeRepoUrl(remoteUrl);
80
+ context.repoFullName = this.extractRepoFullName(remoteUrl);
81
+ }
82
+ }
83
+ catch {
84
+ // No remote
85
+ }
86
+ // Get current branch
87
+ try {
88
+ const branch = (0, child_process_1.execSync)('git rev-parse --abbrev-ref HEAD', {
89
+ cwd,
90
+ encoding: 'utf-8',
91
+ stdio: ['pipe', 'pipe', 'pipe'],
92
+ }).trim();
93
+ if (branch && branch !== 'HEAD') {
94
+ context.branch = branch;
95
+ }
96
+ }
97
+ catch {
98
+ // Not in git repo or detached HEAD
99
+ }
100
+ }
101
+ catch {
102
+ // Git not available
103
+ }
104
+ this.cachedRepo = { cwd, context };
105
+ return context;
106
+ }
107
+ findGitDir(startPath) {
108
+ let current = startPath;
109
+ while (current !== (0, path_1.dirname)(current)) {
110
+ const gitPath = (0, path_1.join)(current, '.git');
111
+ if ((0, fs_1.existsSync)(gitPath)) {
112
+ return gitPath;
113
+ }
114
+ current = (0, path_1.dirname)(current);
115
+ }
116
+ return null;
117
+ }
118
+ normalizeRepoUrl(url) {
119
+ // git@github.com:owner/repo.git -> https://github.com/owner/repo
120
+ let normalized = url
121
+ .replace(/^git@([^:]+):(.+)\.git$/, 'https://$1/$2')
122
+ .replace(/\.git$/, '');
123
+ return normalized;
124
+ }
125
+ extractRepoFullName(url) {
126
+ // Extract owner/repo from various URL formats
127
+ let path = '';
128
+ // SSH format: git@github.com:owner/repo.git
129
+ const sshMatch = /^git@[^:]+:(.+?)(?:\.git)?$/.exec(url);
130
+ if (sshMatch) {
131
+ path = sshMatch[1];
132
+ }
133
+ // HTTPS format: https://github.com/owner/repo.git
134
+ const httpsMatch = /^https?:\/\/[^/]+\/(.+?)(?:\.git)?$/.exec(url);
135
+ if (httpsMatch) {
136
+ path = httpsMatch[1];
137
+ }
138
+ if (!path)
139
+ return undefined;
140
+ // Return owner/repo format
141
+ const parts = path.split('/');
142
+ if (parts.length >= 2) {
143
+ return `${parts[0]}/${parts[1]}`.toLowerCase();
144
+ }
145
+ return undefined;
146
+ }
147
+ getLastActivityAt() {
148
+ return this.lastActivityAt;
149
+ }
150
+ destroy() {
151
+ if (this.idleTimer) {
152
+ clearTimeout(this.idleTimer);
153
+ this.idleTimer = null;
154
+ }
155
+ }
156
+ }
157
+ exports.ActivityDetector = ActivityDetector;
158
+ //# sourceMappingURL=activityDetector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"activityDetector.js","sourceRoot":"","sources":["../../src/terminal/activityDetector.ts"],"names":[],"mappings":"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"}