@techdivision/opencode-time-tracking 0.3.0 → 0.3.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/package.json
CHANGED
package/src/hooks/EventHook.ts
CHANGED
|
@@ -86,7 +86,7 @@ export function createEventHook(
|
|
|
86
86
|
client: OpencodeClient
|
|
87
87
|
) {
|
|
88
88
|
return async ({ event }: { event: Event }): Promise<void> => {
|
|
89
|
-
// Track model from assistant messages
|
|
89
|
+
// Track model and agent from assistant messages
|
|
90
90
|
if (event.type === "message.updated") {
|
|
91
91
|
const props = event.properties as MessageUpdatedProperties
|
|
92
92
|
const message = props.info
|
|
@@ -94,27 +94,28 @@ export function createEventHook(
|
|
|
94
94
|
if (message.role === "assistant") {
|
|
95
95
|
const assistantMsg = message as AssistantMessage
|
|
96
96
|
|
|
97
|
+
// Track model
|
|
97
98
|
if (assistantMsg.modelID && assistantMsg.providerID) {
|
|
98
99
|
sessionManager.setModel(assistantMsg.sessionID, {
|
|
99
100
|
modelID: assistantMsg.modelID,
|
|
100
101
|
providerID: assistantMsg.providerID,
|
|
101
102
|
})
|
|
102
103
|
}
|
|
104
|
+
|
|
105
|
+
// Track agent from mode field
|
|
106
|
+
if (assistantMsg.mode) {
|
|
107
|
+
sessionManager.setAgent(assistantMsg.sessionID, assistantMsg.mode)
|
|
108
|
+
}
|
|
103
109
|
}
|
|
104
110
|
|
|
105
111
|
return
|
|
106
112
|
}
|
|
107
113
|
|
|
108
|
-
// Track token usage
|
|
114
|
+
// Track token usage from message part events
|
|
109
115
|
if (event.type === "message.part.updated") {
|
|
110
116
|
const props = event.properties as MessagePartUpdatedProperties
|
|
111
117
|
const part = props.part
|
|
112
118
|
|
|
113
|
-
// Track agent from agent parts (only first agent is stored)
|
|
114
|
-
if (part.type === "agent" && part.sessionID && part.name) {
|
|
115
|
-
sessionManager.setAgent(part.sessionID, part.name)
|
|
116
|
-
}
|
|
117
|
-
|
|
118
119
|
// Track token usage from step-finish events
|
|
119
120
|
if (part.type === "step-finish" && part.sessionID && part.tokens) {
|
|
120
121
|
sessionManager.addTokenUsage(part.sessionID, {
|
|
@@ -16,6 +16,42 @@ import "../types/Bun"
|
|
|
16
16
|
*/
|
|
17
17
|
const ENV_USER_EMAIL = "OPENCODE_USER_EMAIL"
|
|
18
18
|
|
|
19
|
+
/**
|
|
20
|
+
* Loads a value from a .env file in the specified directory.
|
|
21
|
+
*
|
|
22
|
+
* @param directory - The directory containing the .env file
|
|
23
|
+
* @param key - The environment variable key to look for
|
|
24
|
+
* @returns The value if found, or `null` if not found
|
|
25
|
+
*
|
|
26
|
+
* @internal
|
|
27
|
+
*/
|
|
28
|
+
async function loadEnvValue(
|
|
29
|
+
directory: string,
|
|
30
|
+
key: string
|
|
31
|
+
): Promise<string | null> {
|
|
32
|
+
const envPath = `${directory}/.env`
|
|
33
|
+
|
|
34
|
+
try {
|
|
35
|
+
const file = Bun.file(envPath)
|
|
36
|
+
|
|
37
|
+
if (await file.exists()) {
|
|
38
|
+
const content = await file.text()
|
|
39
|
+
// Match KEY=value, handling optional quotes
|
|
40
|
+
const regex = new RegExp(`^${key}=(.*)$`, "m")
|
|
41
|
+
const match = content.match(regex)
|
|
42
|
+
|
|
43
|
+
if (match) {
|
|
44
|
+
// Remove surrounding quotes (single or double) and trim
|
|
45
|
+
return match[1].trim().replace(/^["']|["']$/g, "")
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return null
|
|
50
|
+
} catch {
|
|
51
|
+
return null
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
19
55
|
/**
|
|
20
56
|
* Loads the plugin configuration from the project directory.
|
|
21
57
|
*
|
|
@@ -23,9 +59,10 @@ const ENV_USER_EMAIL = "OPENCODE_USER_EMAIL"
|
|
|
23
59
|
* The configuration file is expected at `.opencode/opencode-project.json`
|
|
24
60
|
* within the project directory, with a `time_tracking` section.
|
|
25
61
|
*
|
|
26
|
-
* The `user_email` is resolved from:
|
|
27
|
-
* 1. `OPENCODE_USER_EMAIL` environment variable
|
|
28
|
-
* 2.
|
|
62
|
+
* The `user_email` is resolved from (in order of priority):
|
|
63
|
+
* 1. `OPENCODE_USER_EMAIL` system environment variable
|
|
64
|
+
* 2. `OPENCODE_USER_EMAIL` from project `.env` file
|
|
65
|
+
* 3. System username (fallback)
|
|
29
66
|
*/
|
|
30
67
|
export class ConfigLoader {
|
|
31
68
|
/**
|
|
@@ -39,7 +76,7 @@ export class ConfigLoader {
|
|
|
39
76
|
* const config = await ConfigLoader.load("/path/to/project")
|
|
40
77
|
* if (config) {
|
|
41
78
|
* console.log(config.csv_file)
|
|
42
|
-
* console.log(config.user_email) // Resolved from ENV or system username
|
|
79
|
+
* console.log(config.user_email) // Resolved from ENV, .env file, or system username
|
|
43
80
|
* }
|
|
44
81
|
* ```
|
|
45
82
|
*/
|
|
@@ -55,8 +92,13 @@ export class ConfigLoader {
|
|
|
55
92
|
if (projectConfig.time_tracking) {
|
|
56
93
|
const jsonConfig = projectConfig.time_tracking
|
|
57
94
|
|
|
58
|
-
// Resolve user_email
|
|
59
|
-
|
|
95
|
+
// Resolve user_email with fallback chain:
|
|
96
|
+
// 1. System environment variable
|
|
97
|
+
// 2. Project .env file
|
|
98
|
+
// 3. System username
|
|
99
|
+
const envValue = await loadEnvValue(directory, ENV_USER_EMAIL)
|
|
100
|
+
const userEmail =
|
|
101
|
+
process.env[ENV_USER_EMAIL] || envValue || userInfo().username
|
|
60
102
|
|
|
61
103
|
return {
|
|
62
104
|
...jsonConfig,
|