@techdivision/opencode-time-tracking 0.4.0 → 0.6.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/AGENTS.md +12 -5
- package/CHANGELOG.md +54 -0
- package/README.md +95 -3
- package/package.json +1 -1
- package/src/Plugin.ts +1 -1
- package/src/hooks/EventHook.ts +14 -1
- package/src/services/TicketResolver.ts +3 -9
- package/src/types/GlobalDefaultConfig.ts +4 -3
- package/src/types/TimeTrackingConfig.ts +12 -6
package/AGENTS.md
CHANGED
|
@@ -33,7 +33,8 @@ src/
|
|
|
33
33
|
│ ├── ConfigLoader.ts # Load plugin configuration
|
|
34
34
|
│ ├── CsvWriter.ts # CSV file output
|
|
35
35
|
│ ├── SessionManager.ts # Session state management
|
|
36
|
-
│
|
|
36
|
+
│ ├── TicketExtractor.ts # Extract tickets from messages/todos
|
|
37
|
+
│ └── TicketResolver.ts # Resolve tickets with fallback hierarchy
|
|
37
38
|
├── types/ # TypeScript interfaces (one per file)
|
|
38
39
|
│ ├── ActivityData.ts
|
|
39
40
|
│ ├── SessionData.ts
|
|
@@ -196,16 +197,22 @@ export default plugin
|
|
|
196
197
|
|
|
197
198
|
## Configuration
|
|
198
199
|
|
|
199
|
-
Plugin config file: `.opencode/
|
|
200
|
+
Plugin config file: `.opencode/opencode-project.json`
|
|
200
201
|
|
|
201
202
|
```json
|
|
202
203
|
{
|
|
203
|
-
"
|
|
204
|
-
|
|
205
|
-
|
|
204
|
+
"time_tracking": {
|
|
205
|
+
"csv_file": "~/worklogs/time.csv",
|
|
206
|
+
"global_default": {
|
|
207
|
+
"issue_key": "PROJ-MISC",
|
|
208
|
+
"account_key": "ACCOUNT-1"
|
|
209
|
+
}
|
|
210
|
+
}
|
|
206
211
|
}
|
|
207
212
|
```
|
|
208
213
|
|
|
214
|
+
User email is resolved from `OPENCODE_USER_EMAIL` environment variable or system username.
|
|
215
|
+
|
|
209
216
|
## Git Workflow (Gitflow)
|
|
210
217
|
|
|
211
218
|
This project follows **Gitflow**:
|
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
## [0.6.0] - 2025-01-31
|
|
6
|
+
|
|
7
|
+
### Breaking Changes
|
|
8
|
+
|
|
9
|
+
- **Config:** `default_account_key` removed from top-level config
|
|
10
|
+
- **Config:** `global_default` is now required (was optional)
|
|
11
|
+
- **Config:** `global_default.account_key` is now required (was optional)
|
|
12
|
+
|
|
13
|
+
### Migration
|
|
14
|
+
|
|
15
|
+
Update your `.opencode/opencode-project.json`:
|
|
16
|
+
|
|
17
|
+
**Before (0.5.x):**
|
|
18
|
+
```json
|
|
19
|
+
{
|
|
20
|
+
"time_tracking": {
|
|
21
|
+
"csv_file": "...",
|
|
22
|
+
"default_account_key": "TD_KS_1100",
|
|
23
|
+
"global_default": {
|
|
24
|
+
"issue_key": "PROJ-123"
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
**After (0.6.0):**
|
|
31
|
+
```json
|
|
32
|
+
{
|
|
33
|
+
"time_tracking": {
|
|
34
|
+
"csv_file": "...",
|
|
35
|
+
"global_default": {
|
|
36
|
+
"issue_key": "PROJ-123",
|
|
37
|
+
"account_key": "TD_KS_1100"
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Run `/time-tracking.init` to automatically migrate your configuration.
|
|
44
|
+
|
|
45
|
+
## [0.5.0] - 2025-01-28
|
|
46
|
+
|
|
47
|
+
### Added
|
|
48
|
+
|
|
49
|
+
- Initial release
|
|
50
|
+
- Automatic session tracking with ticket extraction
|
|
51
|
+
- CSV export for time entries
|
|
52
|
+
- Agent-specific default tickets
|
|
53
|
+
- Global fallback configuration
|
|
54
|
+
- Ignored agents support
|
package/README.md
CHANGED
|
@@ -23,7 +23,10 @@ Add the `time_tracking` section to your `.opencode/opencode-project.json`:
|
|
|
23
23
|
"$schema": "https://raw.githubusercontent.com/techdivision/opencode-plugins/main/schemas/opencode-project.json",
|
|
24
24
|
"time_tracking": {
|
|
25
25
|
"csv_file": "~/time_tracking/time-tracking.csv",
|
|
26
|
-
"
|
|
26
|
+
"global_default": {
|
|
27
|
+
"issue_key": "PROJ-MISC",
|
|
28
|
+
"account_key": "YOUR_ACCOUNT_KEY"
|
|
29
|
+
}
|
|
27
30
|
}
|
|
28
31
|
}
|
|
29
32
|
```
|
|
@@ -46,11 +49,100 @@ export OPENCODE_USER_EMAIL=your@email.com
|
|
|
46
49
|
|
|
47
50
|
If not set, the system username is used as fallback.
|
|
48
51
|
|
|
52
|
+
## Configuration Options
|
|
53
|
+
|
|
54
|
+
### Required Fields
|
|
55
|
+
|
|
56
|
+
| Field | Description |
|
|
57
|
+
|-------|-------------|
|
|
58
|
+
| `csv_file` | Path to the CSV output file (supports `~/`, absolute, or relative paths) |
|
|
59
|
+
| `global_default.issue_key` | Default JIRA issue key when no ticket found in context |
|
|
60
|
+
| `global_default.account_key` | Default Tempo account key for time entries |
|
|
61
|
+
|
|
62
|
+
### Optional Fields
|
|
63
|
+
|
|
64
|
+
#### Agent-specific Defaults
|
|
65
|
+
|
|
66
|
+
Override default ticket/account for specific agents:
|
|
67
|
+
|
|
68
|
+
```json
|
|
69
|
+
{
|
|
70
|
+
"time_tracking": {
|
|
71
|
+
"csv_file": "...",
|
|
72
|
+
"global_default": {
|
|
73
|
+
"issue_key": "PROJ-MISC",
|
|
74
|
+
"account_key": "TD_GENERAL"
|
|
75
|
+
},
|
|
76
|
+
"agent_defaults": {
|
|
77
|
+
"@developer": {
|
|
78
|
+
"issue_key": "PROJ-DEV",
|
|
79
|
+
"account_key": "TD_DEVELOPMENT"
|
|
80
|
+
},
|
|
81
|
+
"@reviewer": {
|
|
82
|
+
"issue_key": "PROJ-REVIEW"
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
#### Ignored Agents
|
|
90
|
+
|
|
91
|
+
Skip time tracking for specific agents:
|
|
92
|
+
|
|
93
|
+
```json
|
|
94
|
+
{
|
|
95
|
+
"time_tracking": {
|
|
96
|
+
"csv_file": "...",
|
|
97
|
+
"global_default": { ... },
|
|
98
|
+
"ignored_agents": ["@internal", "@notrack"]
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Full Example
|
|
104
|
+
|
|
105
|
+
```json
|
|
106
|
+
{
|
|
107
|
+
"$schema": "https://raw.githubusercontent.com/techdivision/opencode-plugins/main/schemas/opencode-project.json",
|
|
108
|
+
"time_tracking": {
|
|
109
|
+
"csv_file": "~/time_tracking/time-tracking.csv",
|
|
110
|
+
"global_default": {
|
|
111
|
+
"issue_key": "PROJ-MISC",
|
|
112
|
+
"account_key": "TD_GENERAL"
|
|
113
|
+
},
|
|
114
|
+
"agent_defaults": {
|
|
115
|
+
"@developer": {
|
|
116
|
+
"issue_key": "PROJ-DEV",
|
|
117
|
+
"account_key": "TD_DEVELOPMENT"
|
|
118
|
+
},
|
|
119
|
+
"@reviewer": {
|
|
120
|
+
"issue_key": "PROJ-REVIEW"
|
|
121
|
+
}
|
|
122
|
+
},
|
|
123
|
+
"ignored_agents": ["@internal"]
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## Fallback Hierarchy
|
|
129
|
+
|
|
130
|
+
### Ticket Resolution
|
|
131
|
+
|
|
132
|
+
1. Context ticket (from messages/todos)
|
|
133
|
+
2. Agent-specific `issue_key` (if configured)
|
|
134
|
+
3. `global_default.issue_key`
|
|
135
|
+
|
|
136
|
+
### Account Key Resolution
|
|
137
|
+
|
|
138
|
+
1. Agent-specific `account_key` (if configured)
|
|
139
|
+
2. `global_default.account_key`
|
|
140
|
+
|
|
49
141
|
## How it works
|
|
50
142
|
|
|
51
143
|
- Tracks tool executions during each session turn
|
|
52
|
-
- Extracts JIRA ticket from
|
|
53
|
-
- Writes CSV entry when session becomes idle
|
|
144
|
+
- Extracts JIRA ticket from user messages or todos
|
|
145
|
+
- Writes CSV entry when session becomes idle
|
|
54
146
|
- Shows toast notification with tracked time
|
|
55
147
|
|
|
56
148
|
## CSV Format
|
package/package.json
CHANGED
package/src/Plugin.ts
CHANGED
|
@@ -69,7 +69,7 @@ export const plugin: Plugin = async ({
|
|
|
69
69
|
sessionManager,
|
|
70
70
|
ticketExtractor
|
|
71
71
|
),
|
|
72
|
-
event: createEventHook(sessionManager, csvWriter, client, ticketResolver),
|
|
72
|
+
event: createEventHook(sessionManager, csvWriter, client, ticketResolver, config),
|
|
73
73
|
}
|
|
74
74
|
|
|
75
75
|
return hooks
|
package/src/hooks/EventHook.ts
CHANGED
|
@@ -10,6 +10,7 @@ import type { TicketResolver } from "../services/TicketResolver"
|
|
|
10
10
|
import type { MessagePartUpdatedProperties } from "../types/MessagePartUpdatedProperties"
|
|
11
11
|
import type { MessageWithParts } from "../types/MessageWithParts"
|
|
12
12
|
import type { OpencodeClient } from "../types/OpencodeClient"
|
|
13
|
+
import type { TimeTrackingConfig } from "../types/TimeTrackingConfig"
|
|
13
14
|
|
|
14
15
|
import { DescriptionGenerator } from "../utils/DescriptionGenerator"
|
|
15
16
|
|
|
@@ -85,7 +86,8 @@ export function createEventHook(
|
|
|
85
86
|
sessionManager: SessionManager,
|
|
86
87
|
csvWriter: CsvWriter,
|
|
87
88
|
client: OpencodeClient,
|
|
88
|
-
ticketResolver: TicketResolver
|
|
89
|
+
ticketResolver: TicketResolver,
|
|
90
|
+
config: TimeTrackingConfig
|
|
89
91
|
) {
|
|
90
92
|
return async ({ event }: { event: Event }): Promise<void> => {
|
|
91
93
|
// Track model and agent from assistant messages
|
|
@@ -190,6 +192,17 @@ export function createEventHook(
|
|
|
190
192
|
// Get agent name if available
|
|
191
193
|
const agentString = session.agent?.name ?? null
|
|
192
194
|
|
|
195
|
+
// Check if agent should be ignored
|
|
196
|
+
if (agentString && config.ignored_agents?.includes(agentString)) {
|
|
197
|
+
await client.tui.showToast({
|
|
198
|
+
body: {
|
|
199
|
+
message: `Time tracking skipped for ${agentString} (ignored agent)`,
|
|
200
|
+
variant: "info",
|
|
201
|
+
},
|
|
202
|
+
})
|
|
203
|
+
return
|
|
204
|
+
}
|
|
205
|
+
|
|
193
206
|
// Resolve ticket and account key with fallback hierarchy
|
|
194
207
|
const resolved = await ticketResolver.resolve(sessionID, agentString)
|
|
195
208
|
|
|
@@ -18,8 +18,7 @@ import type { TicketExtractor } from "./TicketExtractor"
|
|
|
18
18
|
*
|
|
19
19
|
* Account key fallback hierarchy:
|
|
20
20
|
* 1. Agent-specific account_key
|
|
21
|
-
* 2. Global default account_key
|
|
22
|
-
* 3. default_account_key from config
|
|
21
|
+
* 2. Global default account_key (required)
|
|
23
22
|
*/
|
|
24
23
|
export class TicketResolver {
|
|
25
24
|
/** Plugin configuration */
|
|
@@ -101,12 +100,7 @@ export class TicketResolver {
|
|
|
101
100
|
return this.config.agent_defaults[agentName].account_key!
|
|
102
101
|
}
|
|
103
102
|
|
|
104
|
-
// 2. Global default account_key
|
|
105
|
-
|
|
106
|
-
return this.config.global_default.account_key
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
// 3. Config default
|
|
110
|
-
return this.config.default_account_key
|
|
103
|
+
// 2. Global default account_key (required)
|
|
104
|
+
return this.config.global_default.account_key
|
|
111
105
|
}
|
|
112
106
|
}
|
|
@@ -19,10 +19,11 @@ export interface GlobalDefaultConfig {
|
|
|
19
19
|
issue_key: string
|
|
20
20
|
|
|
21
21
|
/**
|
|
22
|
-
*
|
|
22
|
+
* Default Tempo Account Key.
|
|
23
23
|
*
|
|
24
24
|
* @remarks
|
|
25
|
-
*
|
|
25
|
+
* Required. Used as the default account for all time entries
|
|
26
|
+
* unless overridden by agent-specific configuration.
|
|
26
27
|
*/
|
|
27
|
-
account_key
|
|
28
|
+
account_key: string
|
|
28
29
|
}
|
|
@@ -25,8 +25,14 @@ export interface TimeTrackingJsonConfig {
|
|
|
25
25
|
*/
|
|
26
26
|
csv_file: string
|
|
27
27
|
|
|
28
|
-
/**
|
|
29
|
-
|
|
28
|
+
/**
|
|
29
|
+
* Global fallback ticket and account configuration.
|
|
30
|
+
*
|
|
31
|
+
* @remarks
|
|
32
|
+
* Required. Contains the default issue_key and account_key used when
|
|
33
|
+
* no ticket is found in context and no agent-specific default is configured.
|
|
34
|
+
*/
|
|
35
|
+
global_default: GlobalDefaultConfig
|
|
30
36
|
|
|
31
37
|
/**
|
|
32
38
|
* Agent-specific default tickets.
|
|
@@ -38,13 +44,13 @@ export interface TimeTrackingJsonConfig {
|
|
|
38
44
|
agent_defaults?: Record<string, AgentDefaultConfig>
|
|
39
45
|
|
|
40
46
|
/**
|
|
41
|
-
*
|
|
47
|
+
* List of agent names to ignore for time tracking.
|
|
42
48
|
*
|
|
43
49
|
* @remarks
|
|
44
|
-
*
|
|
45
|
-
*
|
|
50
|
+
* Sessions triggered by these agents will not be exported to CSV.
|
|
51
|
+
* Agent names should include the "@" prefix (e.g., "@internal").
|
|
46
52
|
*/
|
|
47
|
-
|
|
53
|
+
ignored_agents?: string[]
|
|
48
54
|
}
|
|
49
55
|
|
|
50
56
|
/**
|