opencode-codetime 0.3.0 → 0.4.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/dist/git.d.ts +4 -9
- package/dist/git.js +26 -16
- package/dist/index.js +12 -46
- package/package.json +1 -1
package/dist/git.d.ts
CHANGED
|
@@ -1,15 +1,10 @@
|
|
|
1
|
-
interface ShellFn {
|
|
2
|
-
(strings: TemplateStringsArray, ...values: unknown[]): Promise<{
|
|
3
|
-
stdout: Buffer;
|
|
4
|
-
exitCode: number;
|
|
5
|
-
}>;
|
|
6
|
-
}
|
|
7
1
|
/**
|
|
8
2
|
* Extract git remote origin URL from the worktree.
|
|
3
|
+
* Uses node:child_process directly to avoid OpenCode TUI shell flash.
|
|
9
4
|
*/
|
|
10
|
-
export declare function getGitOrigin(
|
|
5
|
+
export declare function getGitOrigin(worktree: string): Promise<string | null>;
|
|
11
6
|
/**
|
|
12
7
|
* Extract the current git branch from the worktree.
|
|
8
|
+
* Uses node:child_process directly to avoid OpenCode TUI shell flash.
|
|
13
9
|
*/
|
|
14
|
-
export declare function getGitBranch(
|
|
15
|
-
export {};
|
|
10
|
+
export declare function getGitBranch(worktree: string): Promise<string | null>;
|
package/dist/git.js
CHANGED
|
@@ -1,32 +1,42 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { execFile as execFileCb } from "node:child_process";
|
|
2
|
+
import { promisify } from "node:util";
|
|
3
|
+
const execFile = promisify(execFileCb);
|
|
2
4
|
/**
|
|
3
5
|
* Extract git remote origin URL from the worktree.
|
|
6
|
+
* Uses node:child_process directly to avoid OpenCode TUI shell flash.
|
|
4
7
|
*/
|
|
5
|
-
export async function getGitOrigin(
|
|
8
|
+
export async function getGitOrigin(worktree) {
|
|
6
9
|
try {
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
10
|
+
const { stdout } = await execFile("git", [
|
|
11
|
+
"-C",
|
|
12
|
+
worktree,
|
|
13
|
+
"config",
|
|
14
|
+
"--get",
|
|
15
|
+
"remote.origin.url",
|
|
16
|
+
]);
|
|
17
|
+
return stdout.trim() || null;
|
|
11
18
|
}
|
|
12
19
|
catch {
|
|
13
|
-
|
|
20
|
+
return null;
|
|
14
21
|
}
|
|
15
|
-
return null;
|
|
16
22
|
}
|
|
17
23
|
/**
|
|
18
24
|
* Extract the current git branch from the worktree.
|
|
25
|
+
* Uses node:child_process directly to avoid OpenCode TUI shell flash.
|
|
19
26
|
*/
|
|
20
|
-
export async function getGitBranch(
|
|
27
|
+
export async function getGitBranch(worktree) {
|
|
21
28
|
try {
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
29
|
+
const { stdout } = await execFile("git", [
|
|
30
|
+
"-C",
|
|
31
|
+
worktree,
|
|
32
|
+
"rev-parse",
|
|
33
|
+
"--abbrev-ref",
|
|
34
|
+
"HEAD",
|
|
35
|
+
]);
|
|
36
|
+
const branch = stdout.trim();
|
|
37
|
+
return branch && branch !== "HEAD" ? branch : null;
|
|
27
38
|
}
|
|
28
39
|
catch {
|
|
29
|
-
|
|
40
|
+
return null;
|
|
30
41
|
}
|
|
31
|
-
return null;
|
|
32
42
|
}
|
package/dist/index.js
CHANGED
|
@@ -10,11 +10,9 @@ import { initState, shouldSendHeartbeat, updateLastHeartbeat, } from "./state.js
|
|
|
10
10
|
const processedCallIds = new Set();
|
|
11
11
|
const pendingFiles = new Map();
|
|
12
12
|
let _token = null;
|
|
13
|
-
let _client = null;
|
|
14
13
|
let _projectName = "unknown";
|
|
15
14
|
let _projectDir = "";
|
|
16
15
|
let _worktree = "";
|
|
17
|
-
let _shellFn = null;
|
|
18
16
|
let _gitOrigin = null;
|
|
19
17
|
let _gitBranch = null;
|
|
20
18
|
let _gitInfoFetched = false;
|
|
@@ -86,12 +84,12 @@ function computeRelativeFile(absoluteFile, projectDir) {
|
|
|
86
84
|
}
|
|
87
85
|
// ---- Lazy git info ----
|
|
88
86
|
async function ensureGitInfo() {
|
|
89
|
-
if (_gitInfoFetched || !
|
|
87
|
+
if (_gitInfoFetched || !_worktree)
|
|
90
88
|
return;
|
|
91
89
|
_gitInfoFetched = true;
|
|
92
90
|
try {
|
|
93
|
-
_gitOrigin = await getGitOrigin(
|
|
94
|
-
_gitBranch = await getGitBranch(
|
|
91
|
+
_gitOrigin = await getGitOrigin(_worktree);
|
|
92
|
+
_gitBranch = await getGitBranch(_worktree);
|
|
95
93
|
await debug("Git info", { origin: _gitOrigin, branch: _gitBranch }).catch(() => { });
|
|
96
94
|
}
|
|
97
95
|
catch {
|
|
@@ -168,7 +166,7 @@ function formatMinutes(minutes) {
|
|
|
168
166
|
// ---- Plugin entry point ----
|
|
169
167
|
export const plugin = async (ctx) => {
|
|
170
168
|
try {
|
|
171
|
-
const { client, directory, worktree
|
|
169
|
+
const { client, directory, worktree } = ctx;
|
|
172
170
|
// Initialize logger (may fail if client shape differs)
|
|
173
171
|
try {
|
|
174
172
|
initLogger(client);
|
|
@@ -195,13 +193,10 @@ export const plugin = async (ctx) => {
|
|
|
195
193
|
}).catch(() => { });
|
|
196
194
|
// Initialize state
|
|
197
195
|
initState();
|
|
198
|
-
_client = client;
|
|
199
196
|
_projectDir = directory;
|
|
200
197
|
_worktree = worktree;
|
|
201
198
|
_projectName = `${path.basename(directory)} [opencode]`;
|
|
202
199
|
_platform = os.platform();
|
|
203
|
-
// Store shell function for lazy git info fetching
|
|
204
|
-
_shellFn = $;
|
|
205
200
|
return {
|
|
206
201
|
event: async ({ event }) => {
|
|
207
202
|
try {
|
|
@@ -258,43 +253,14 @@ export const plugin = async (ctx) => {
|
|
|
258
253
|
await error("Chat message handler error", { error: String(err) }).catch(() => { });
|
|
259
254
|
}
|
|
260
255
|
},
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
output.parts.push({
|
|
270
|
-
type: "text",
|
|
271
|
-
text: "CodeTime is not configured. Set `CODETIME_TOKEN` environment variable to enable tracking.\nGet your token from https://codetime.dev/dashboard/settings",
|
|
272
|
-
});
|
|
273
|
-
return;
|
|
274
|
-
}
|
|
275
|
-
const minutes = await getTodayMinutes(_token);
|
|
276
|
-
if (minutes === null) {
|
|
277
|
-
await _client.tui.showToast({
|
|
278
|
-
body: { message: "CodeTime: failed to fetch data", variant: "error" },
|
|
279
|
-
}).catch(() => { });
|
|
280
|
-
output.parts.push({
|
|
281
|
-
type: "text",
|
|
282
|
-
text: "Failed to fetch coding time from CodeTime API.",
|
|
283
|
-
});
|
|
284
|
-
return;
|
|
285
|
-
}
|
|
286
|
-
const formatted = formatMinutes(minutes);
|
|
287
|
-
await _client.tui.showToast({
|
|
288
|
-
body: { message: `CodeTime: ${formatted} today`, variant: "success" },
|
|
289
|
-
}).catch(() => { });
|
|
290
|
-
output.parts.push({
|
|
291
|
-
type: "text",
|
|
292
|
-
text: `Today's coding time: ${formatted}`,
|
|
293
|
-
});
|
|
294
|
-
}
|
|
295
|
-
catch (err) {
|
|
296
|
-
await error("Command handler error", { error: String(err) }).catch(() => { });
|
|
297
|
-
}
|
|
256
|
+
config: async (cfg) => {
|
|
257
|
+
cfg.command = cfg.command || {};
|
|
258
|
+
cfg.command["codetime"] = {
|
|
259
|
+
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
|
+
};
|
|
298
264
|
},
|
|
299
265
|
tool: {
|
|
300
266
|
codetime: tool({
|