opencode-codetime 0.5.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.
Files changed (2) hide show
  1. package/dist/index.js +55 -16
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -163,6 +163,22 @@ function formatMinutes(minutes) {
163
163
  return `${hours}h`;
164
164
  return `${hours}h ${mins}m`;
165
165
  }
166
+ /**
167
+ * Format a project field for display by wrapping the suffix in brackets.
168
+ * If the field already contains '[', it's returned as-is.
169
+ * Otherwise, everything after the first space is treated as a suffix.
170
+ * E.g. "test WSL: Ubuntu-24.04" → "test [WSL: Ubuntu-24.04]"
171
+ */
172
+ function formatProjectName(field) {
173
+ if (field.includes("["))
174
+ return field;
175
+ const spaceIdx = field.indexOf(" ");
176
+ if (spaceIdx === -1)
177
+ return field;
178
+ const name = field.substring(0, spaceIdx);
179
+ const suffix = field.substring(spaceIdx + 1);
180
+ return `${name} [${suffix}]`;
181
+ }
166
182
  // ---- Plugin entry point ----
167
183
  export const plugin = async (ctx) => {
168
184
  try {
@@ -179,12 +195,32 @@ export const plugin = async (ctx) => {
179
195
  if (!_token) {
180
196
  await warn("CODETIME_TOKEN not set. CodeTime tracking disabled. " +
181
197
  "Get your token from https://codetime.dev/dashboard/settings").catch(() => { });
198
+ try {
199
+ await client.tui.showToast({
200
+ body: {
201
+ title: "CodeTime",
202
+ message: "CODETIME_TOKEN not set. Tracking disabled.",
203
+ variant: "error",
204
+ },
205
+ });
206
+ }
207
+ catch { }
182
208
  return {};
183
209
  }
184
210
  // Validate token
185
211
  const user = await validateToken(_token);
186
212
  if (!user) {
187
213
  await error("Invalid CODETIME_TOKEN. Please check your token at https://codetime.dev/dashboard/settings").catch(() => { });
214
+ try {
215
+ await client.tui.showToast({
216
+ body: {
217
+ title: "CodeTime",
218
+ message: "Invalid token. Check https://codetime.dev/dashboard/settings",
219
+ variant: "error",
220
+ },
221
+ });
222
+ }
223
+ catch { }
188
224
  _token = null;
189
225
  return {};
190
226
  }
@@ -257,15 +293,12 @@ export const plugin = async (ctx) => {
257
293
  cfg.command = cfg.command || {};
258
294
  cfg.command["codetime"] = {
259
295
  description: "Show today's coding time from CodeTime",
260
- template: "Retrieve current CodeTime coding time stats.\n\n" +
261
- "Immediately call `codetime` with no arguments and return its output verbatim.\n" +
262
- "Do not call other tools.",
263
- };
264
- cfg.command["codetime-breakdown"] = {
265
- description: "Show today's coding time breakdown by project",
266
- template: "Retrieve CodeTime coding time stats broken down by project.\n\n" +
267
- 'Immediately call `codetime` with `breakdown: true` and return its output verbatim.\n' +
268
- "Do not call other tools.",
296
+ template: "Retrieve CodeTime coding time stats.\n\n" +
297
+ "Based on the arguments provided: `$ARGUMENTS`\n\n" +
298
+ '- If no arguments (empty/blank), call `codetime` with `project: "current"` to show current project time.\n' +
299
+ "- If the argument is `breakdown`, call `codetime` with `breakdown: true` to show all projects.\n" +
300
+ "- Otherwise, call `codetime` with `project` set to the argument value to show that specific project's time.\n\n" +
301
+ "Return the output verbatim. Do not call other tools.",
269
302
  };
270
303
  },
271
304
  tool: {
@@ -292,15 +325,21 @@ export const plugin = async (ctx) => {
292
325
  }
293
326
  // Calculate total
294
327
  const totalMinutes = projects.reduce((sum, p) => sum + p.minutes, 0);
295
- // Find the longest project name for alignment
296
- const maxNameLen = Math.max(...projects.map((p) => p.field.length), "Total".length);
328
+ // Pre-compute display names and formatted times
329
+ const displayNames = projects.map((p) => formatProjectName(p.field));
330
+ const formattedTimes = projects.map((p) => formatMinutes(p.minutes));
331
+ const totalTime = formatMinutes(totalMinutes);
332
+ // Find the longest display name and time for alignment
333
+ const maxNameLen = Math.max(...displayNames.map((n) => n.length), "Total".length);
334
+ const maxTimeLen = Math.max(...formattedTimes.map((t) => t.length), totalTime.length);
297
335
  const lines = ["Today's coding time by project:", ""];
298
- for (const p of projects) {
299
- const name = p.field.padEnd(maxNameLen + 2);
300
- lines.push(` ${name}${formatMinutes(p.minutes)}`);
336
+ for (let i = 0; i < projects.length; i++) {
337
+ const name = displayNames[i].padEnd(maxNameLen + 2);
338
+ const time = formattedTimes[i].padStart(maxTimeLen);
339
+ lines.push(` ${name}${time}`);
301
340
  }
302
- lines.push(` ${"─".repeat(maxNameLen + 2 + 8)}`);
303
- lines.push(` ${"Total".padEnd(maxNameLen + 2)}${formatMinutes(totalMinutes)}`);
341
+ lines.push(` ${"─".repeat(maxNameLen + 2 + maxTimeLen)}`);
342
+ lines.push(` ${"Total".padEnd(maxNameLen + 2)}${totalTime.padStart(maxTimeLen)}`);
304
343
  return lines.join("\n");
305
344
  }
306
345
  // Project-specific mode
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-codetime",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "description": "CodeTime plugin for OpenCode - Track AI coding activity and time spent with codetime.dev",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",