codex-wakatime 1.0.0 → 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.
Files changed (3) hide show
  1. package/README.md +10 -4
  2. package/dist/index.cjs +101 -17
  3. package/package.json +15 -5
package/README.md CHANGED
@@ -1,6 +1,14 @@
1
1
  # codex-wakatime
2
2
 
3
- WakaTime integration for [OpenAI Codex CLI](https://github.com/openai/codex) - Track AI coding activity and time spent.
3
+ [![npm version](https://img.shields.io/npm/v/codex-wakatime)](https://www.npmjs.com/package/codex-wakatime)
4
+ [![npm downloads](https://img.shields.io/npm/dm/codex-wakatime)](https://www.npmjs.com/package/codex-wakatime)
5
+ [![CI](https://github.com/angristan/codex-wakatime/actions/workflows/workflow.yml/badge.svg)](https://github.com/angristan/codex-wakatime/actions/workflows/workflow.yml)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
7
+
8
+ WakaTime integration for [OpenAI Codex CLI](https://github.com/openai/codex). Track AI coding activity and time spent.
9
+
10
+ > [!TIP]
11
+ > Also check out [opencode-wakatime](https://github.com/angristan/opencode-wakatime) for OpenCode!
4
12
 
5
13
  ## Features
6
14
 
@@ -114,7 +122,7 @@ Logs are written to `~/.wakatime/codex.log`.
114
122
 
115
123
  ```bash
116
124
  # Clone the repository
117
- git clone https://github.com/wakatime/codex-wakatime
125
+ git clone https://github.com/angristan/codex-wakatime
118
126
  cd codex-wakatime
119
127
 
120
128
  # Install dependencies
@@ -148,8 +156,6 @@ codex-wakatime/
148
156
  │ ├── options.ts # Config parsing
149
157
  │ ├── types.ts # TypeScript interfaces
150
158
  │ └── __tests__/ # Test files
151
- ├── scripts/
152
- │ └── generate-version.js
153
159
  ├── package.json
154
160
  ├── tsconfig.json
155
161
  └── biome.json
package/dist/index.cjs CHANGED
@@ -279,16 +279,17 @@ var path7 = __toESM(require("node:path"), 1);
279
279
 
280
280
  // src/extractor.ts
281
281
  var path = __toESM(require("node:path"), 1);
282
- var PATTERNS = [
282
+ var READ_PATTERNS = [
283
283
  // Code block headers: ```typescript:src/index.ts or ```ts:src/index.ts
284
284
  /```\w*:([^\n`]+)/g,
285
285
  // Backtick paths with extension: `src/foo/bar.ts`
286
286
  /`([^`\s]+\.\w{1,6})`/g,
287
- // Action patterns: Created/Modified/Updated/Wrote/Edited/Deleted file.ts
288
- /(?:Created|Modified|Updated|Wrote|Edited|Deleted|Reading|Writing)\s+`?([^\s`\n]+\.\w{1,6})`?/gi,
289
287
  // File path in quotes: "src/file.ts" or 'src/file.ts'
290
- /["']([^"'\s]+\.\w{1,6})["']/g
288
+ /["']([^"'\s]+\.\w{1,6})["']/g,
289
+ // Read action patterns: Read/List file.ts
290
+ /(?:Read|List)\s+`?([^\s`\n]+\.\w{1,6})`?/gi
291
291
  ];
292
+ var WRITE_PATTERN = /(?:Create|Created|Modify|Modified|Update|Updated|Write|Wrote|Edit|Edited|Delete|Deleted)\s+`?([^\s`\n]+\.\w{1,6})`?/gi;
292
293
  function isValidFilePath(p) {
293
294
  if (!p || p.length === 0) return false;
294
295
  if (p.startsWith("http://") || p.startsWith("https://") || p.includes("://"))
@@ -306,22 +307,35 @@ function normalizePath(filePath, cwd) {
306
307
  }
307
308
  return path.normalize(path.join(cwd, cleaned));
308
309
  }
309
- function extractFilePaths(message, cwd) {
310
+ function extractFiles(message, cwd) {
310
311
  if (!message || message.length === 0) {
311
312
  return [];
312
313
  }
313
- const files = /* @__PURE__ */ new Set();
314
- for (const pattern of PATTERNS) {
314
+ const fileMap = /* @__PURE__ */ new Map();
315
+ WRITE_PATTERN.lastIndex = 0;
316
+ for (const match of message.matchAll(WRITE_PATTERN)) {
317
+ const filePath = match[1];
318
+ if (filePath && isValidFilePath(filePath)) {
319
+ const normalized = normalizePath(filePath, cwd);
320
+ fileMap.set(normalized, true);
321
+ }
322
+ }
323
+ for (const pattern of READ_PATTERNS) {
315
324
  pattern.lastIndex = 0;
316
325
  for (const match of message.matchAll(pattern)) {
317
326
  const filePath = match[1];
318
327
  if (filePath && isValidFilePath(filePath)) {
319
328
  const normalized = normalizePath(filePath, cwd);
320
- files.add(normalized);
329
+ if (!fileMap.has(normalized)) {
330
+ fileMap.set(normalized, false);
331
+ }
321
332
  }
322
333
  }
323
334
  }
324
- return Array.from(files);
335
+ return Array.from(fileMap.entries()).map(([filePath, isWrite]) => ({
336
+ path: filePath,
337
+ isWrite
338
+ }));
325
339
  }
326
340
 
327
341
  // src/install.ts
@@ -427,7 +441,9 @@ function normalizeNotifyValue(value) {
427
441
  return [];
428
442
  }
429
443
  function hasNotifyEntry(entries, command) {
430
- return entries.some((entry) => typeof entry === "string" && entry === command);
444
+ return entries.some(
445
+ (entry) => typeof entry === "string" && entry === command
446
+ );
431
447
  }
432
448
  function removeNotifyEntry(entries, command) {
433
449
  return entries.filter(
@@ -641,6 +657,73 @@ function updateLastHeartbeat() {
641
657
  var import_node_child_process = require("node:child_process");
642
658
  var os6 = __toESM(require("node:os"), 1);
643
659
 
660
+ // package.json
661
+ var package_default = {
662
+ $schema: "https://json.schemastore.org/package.json",
663
+ name: "codex-wakatime",
664
+ version: "1.1.0",
665
+ description: "WakaTime plugin for OpenAI Codex CLI - Track AI coding activity and time spent",
666
+ repository: {
667
+ type: "git",
668
+ url: "https://github.com/angristan/codex-wakatime.git"
669
+ },
670
+ type: "module",
671
+ main: "dist/index.cjs",
672
+ types: "dist/index.d.ts",
673
+ bin: {
674
+ "codex-wakatime": "dist/index.cjs"
675
+ },
676
+ files: [
677
+ "dist"
678
+ ],
679
+ scripts: {
680
+ build: 'esbuild src/index.ts --bundle --platform=node --format=cjs --outfile=dist/index.cjs --banner:js="#!/usr/bin/env node"',
681
+ typecheck: "tsc --noEmit",
682
+ lint: "biome lint .",
683
+ format: "biome format --write .",
684
+ check: "biome check .",
685
+ test: "vitest",
686
+ "test:run": "vitest run",
687
+ "test:coverage": "vitest run --coverage",
688
+ prepublishOnly: "npm run build",
689
+ prepare: "husky"
690
+ },
691
+ keywords: [
692
+ "codex",
693
+ "openai",
694
+ "wakatime",
695
+ "time-tracking",
696
+ "ai",
697
+ "coding",
698
+ "productivity"
699
+ ],
700
+ author: "WakaTime",
701
+ license: "MIT",
702
+ devDependencies: {
703
+ "@biomejs/biome": "^2.3.10",
704
+ "@semantic-release/changelog": "^6.0.3",
705
+ "@semantic-release/git": "^10.0.1",
706
+ "@types/node": "^22.0.0",
707
+ "@types/which": "^3.0.0",
708
+ "@vitest/coverage-v8": "^4.0.16",
709
+ esbuild: "^0.25.0",
710
+ husky: "^9.1.7",
711
+ "lint-staged": "^16.2.7",
712
+ "semantic-release": "^25.0.2",
713
+ typescript: "^5.0.0",
714
+ vitest: "^4.0.16"
715
+ },
716
+ dependencies: {
717
+ "@iarna/toml": "^3.0.0",
718
+ which: "^4.0.0"
719
+ },
720
+ "lint-staged": {
721
+ "*.{ts,js,json}": [
722
+ "biome check --write"
723
+ ]
724
+ }
725
+ };
726
+
644
727
  // src/dependencies.ts
645
728
  var fs5 = __toESM(require("node:fs"), 1);
646
729
  var import_node_fs = require("node:fs");
@@ -913,10 +996,8 @@ var Dependencies = class {
913
996
  };
914
997
  var dependencies = new Dependencies();
915
998
 
916
- // src/version.ts
917
- var VERSION = "1.0.0";
918
-
919
999
  // src/wakatime.ts
1000
+ var VERSION = package_default.version;
920
1001
  function isWindows() {
921
1002
  return os6.platform() === "win32";
922
1003
  }
@@ -1040,16 +1121,19 @@ async function main() {
1040
1121
  }
1041
1122
  const assistantMessage = notification["last-assistant-message"] ?? "";
1042
1123
  const cwd = notification.cwd;
1043
- const files = extractFilePaths(assistantMessage, cwd);
1124
+ const files = extractFiles(assistantMessage, cwd);
1044
1125
  logger.debug(`Extracted ${files.length} files from message`);
1045
1126
  if (files.length > 0) {
1046
1127
  for (const file of files) {
1047
- logger.debug(`Sending heartbeat for file: ${file}`);
1128
+ logger.debug(
1129
+ `Sending heartbeat for file: ${file.path} (isWrite: ${file.isWrite})`
1130
+ );
1048
1131
  sendHeartbeat({
1049
- entity: file,
1132
+ entity: file.path,
1050
1133
  entityType: "file",
1051
1134
  category: "ai coding",
1052
- projectFolder: cwd
1135
+ projectFolder: cwd,
1136
+ isWrite: file.isWrite
1053
1137
  });
1054
1138
  }
1055
1139
  } else {
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
3
  "name": "codex-wakatime",
4
- "version": "1.0.0",
4
+ "version": "1.1.0",
5
5
  "description": "WakaTime plugin for OpenAI Codex CLI - Track AI coding activity and time spent",
6
6
  "repository": {
7
7
  "type": "git",
8
- "url": "https://github.com/wakatime/codex-wakatime.git"
8
+ "url": "https://github.com/angristan/codex-wakatime.git"
9
9
  },
10
10
  "type": "module",
11
11
  "main": "dist/index.cjs",
@@ -17,8 +17,7 @@
17
17
  "dist"
18
18
  ],
19
19
  "scripts": {
20
- "prebuild": "node scripts/generate-version.js",
21
- "build": "npm run prebuild && esbuild src/index.ts --bundle --platform=node --format=cjs --outfile=dist/index.cjs --banner:js=\"#!/usr/bin/env node\"",
20
+ "build": "esbuild src/index.ts --bundle --platform=node --format=cjs --outfile=dist/index.cjs --banner:js=\"#!/usr/bin/env node\"",
22
21
  "typecheck": "tsc --noEmit",
23
22
  "lint": "biome lint .",
24
23
  "format": "biome format --write .",
@@ -26,7 +25,8 @@
26
25
  "test": "vitest",
27
26
  "test:run": "vitest run",
28
27
  "test:coverage": "vitest run --coverage",
29
- "prepublishOnly": "npm run build"
28
+ "prepublishOnly": "npm run build",
29
+ "prepare": "husky"
30
30
  },
31
31
  "keywords": [
32
32
  "codex",
@@ -41,15 +41,25 @@
41
41
  "license": "MIT",
42
42
  "devDependencies": {
43
43
  "@biomejs/biome": "^2.3.10",
44
+ "@semantic-release/changelog": "^6.0.3",
45
+ "@semantic-release/git": "^10.0.1",
44
46
  "@types/node": "^22.0.0",
45
47
  "@types/which": "^3.0.0",
46
48
  "@vitest/coverage-v8": "^4.0.16",
47
49
  "esbuild": "^0.25.0",
50
+ "husky": "^9.1.7",
51
+ "lint-staged": "^16.2.7",
52
+ "semantic-release": "^25.0.2",
48
53
  "typescript": "^5.0.0",
49
54
  "vitest": "^4.0.16"
50
55
  },
51
56
  "dependencies": {
52
57
  "@iarna/toml": "^3.0.0",
53
58
  "which": "^4.0.0"
59
+ },
60
+ "lint-staged": {
61
+ "*.{ts,js,json}": [
62
+ "biome check --write"
63
+ ]
54
64
  }
55
65
  }