@techdivision/opencode-time-tracking 0.5.0 → 0.6.1
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 +61 -0
- package/README.md +95 -3
- package/package.json +1 -1
- package/src/hooks/EventHook.ts +7 -2
- package/src/services/TicketResolver.ts +3 -9
- package/src/types/GlobalDefaultConfig.ts +4 -3
- package/src/types/TimeTrackingConfig.ts +8 -11
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,61 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
## [0.6.1] - 2025-02-02
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
|
|
9
|
+
- Fix `ignored_agents` matching to accept agent names with or without `@` prefix
|
|
10
|
+
- Both `"time-tracking"` and `"@time-tracking"` now work in configuration
|
|
11
|
+
|
|
12
|
+
## [0.6.0] - 2025-01-31
|
|
13
|
+
|
|
14
|
+
### Breaking Changes
|
|
15
|
+
|
|
16
|
+
- **Config:** `default_account_key` removed from top-level config
|
|
17
|
+
- **Config:** `global_default` is now required (was optional)
|
|
18
|
+
- **Config:** `global_default.account_key` is now required (was optional)
|
|
19
|
+
|
|
20
|
+
### Migration
|
|
21
|
+
|
|
22
|
+
Update your `.opencode/opencode-project.json`:
|
|
23
|
+
|
|
24
|
+
**Before (0.5.x):**
|
|
25
|
+
```json
|
|
26
|
+
{
|
|
27
|
+
"time_tracking": {
|
|
28
|
+
"csv_file": "...",
|
|
29
|
+
"default_account_key": "TD_KS_1100",
|
|
30
|
+
"global_default": {
|
|
31
|
+
"issue_key": "PROJ-123"
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
**After (0.6.0):**
|
|
38
|
+
```json
|
|
39
|
+
{
|
|
40
|
+
"time_tracking": {
|
|
41
|
+
"csv_file": "...",
|
|
42
|
+
"global_default": {
|
|
43
|
+
"issue_key": "PROJ-123",
|
|
44
|
+
"account_key": "TD_KS_1100"
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Run `/time-tracking.init` to automatically migrate your configuration.
|
|
51
|
+
|
|
52
|
+
## [0.5.0] - 2025-01-28
|
|
53
|
+
|
|
54
|
+
### Added
|
|
55
|
+
|
|
56
|
+
- Initial release
|
|
57
|
+
- Automatic session tracking with ticket extraction
|
|
58
|
+
- CSV export for time entries
|
|
59
|
+
- Agent-specific default tickets
|
|
60
|
+
- Global fallback configuration
|
|
61
|
+
- 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/hooks/EventHook.ts
CHANGED
|
@@ -192,8 +192,13 @@ export function createEventHook(
|
|
|
192
192
|
// Get agent name if available
|
|
193
193
|
const agentString = session.agent?.name ?? null
|
|
194
194
|
|
|
195
|
-
// Check if agent should be ignored
|
|
196
|
-
|
|
195
|
+
// Check if agent should be ignored (tolerant matching: with or without @ prefix)
|
|
196
|
+
const normalizedAgent = agentString?.replace(/^@/, "")
|
|
197
|
+
const isIgnoredAgent = config.ignored_agents?.some(
|
|
198
|
+
(ignored) => ignored.replace(/^@/, "") === normalizedAgent
|
|
199
|
+
)
|
|
200
|
+
|
|
201
|
+
if (agentString && isIgnoredAgent) {
|
|
197
202
|
await client.tui.showToast({
|
|
198
203
|
body: {
|
|
199
204
|
message: `Time tracking skipped for ${agentString} (ignored agent)`,
|
|
@@ -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,26 +25,23 @@ export interface TimeTrackingJsonConfig {
|
|
|
25
25
|
*/
|
|
26
26
|
csv_file: string
|
|
27
27
|
|
|
28
|
-
/** Default Jira account key for time entries */
|
|
29
|
-
default_account_key: string
|
|
30
|
-
|
|
31
28
|
/**
|
|
32
|
-
*
|
|
29
|
+
* Global fallback ticket and account configuration.
|
|
33
30
|
*
|
|
34
31
|
* @remarks
|
|
35
|
-
*
|
|
36
|
-
*
|
|
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.
|
|
37
34
|
*/
|
|
38
|
-
|
|
35
|
+
global_default: GlobalDefaultConfig
|
|
39
36
|
|
|
40
37
|
/**
|
|
41
|
-
*
|
|
38
|
+
* Agent-specific default tickets.
|
|
42
39
|
*
|
|
43
40
|
* @remarks
|
|
44
|
-
*
|
|
45
|
-
* default is
|
|
41
|
+
* Map of agent names (e.g., "@developer", "@reviewer") to their
|
|
42
|
+
* default ticket configuration. Used when no ticket is found in context.
|
|
46
43
|
*/
|
|
47
|
-
|
|
44
|
+
agent_defaults?: Record<string, AgentDefaultConfig>
|
|
48
45
|
|
|
49
46
|
/**
|
|
50
47
|
* List of agent names to ignore for time tracking.
|