@wibeco/bridge 0.2.5 → 0.2.6
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.
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
startPresenceSession,
|
|
18
18
|
stopPresenceSession,
|
|
19
19
|
updatePresenceSession
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-WVBSXZG3.js";
|
|
21
21
|
|
|
22
22
|
// src/cli/commands.ts
|
|
23
23
|
import { access, cp, mkdir, readFile, writeFile } from "fs/promises";
|
|
@@ -193,7 +193,7 @@ async function emitCommand(adapter, eventName, input) {
|
|
|
193
193
|
const mapper = adapter === "cursor" ? mapCursorHook : adapter === "claude-code" ? mapClaudeCodeHook : mapCodexHook;
|
|
194
194
|
let mappedEvent = mapper(eventName, input);
|
|
195
195
|
const repo = await detectRepository(process.cwd());
|
|
196
|
-
if (repo && (mappedEvent.kind === "session.started" || mappedEvent.kind === "session.ended" || mappedEvent.kind === "presence.heartbeat" || mappedEvent.kind === "file.changed")) {
|
|
196
|
+
if (repo && (mappedEvent.kind === "session.started" || mappedEvent.kind === "session.ended" || mappedEvent.kind === "lifecycle.before" || mappedEvent.kind === "presence.heartbeat" || mappedEvent.kind === "file.changed")) {
|
|
197
197
|
const workingTree = await detectWorkingTreeMetrics(repo.root);
|
|
198
198
|
if (workingTree) {
|
|
199
199
|
mappedEvent = {
|
|
@@ -232,18 +232,29 @@ async function emitCommand(adapter, eventName, input) {
|
|
|
232
232
|
};
|
|
233
233
|
}
|
|
234
234
|
} else {
|
|
235
|
-
|
|
235
|
+
let metrics = await updatePresenceSession(
|
|
236
236
|
adapter,
|
|
237
237
|
mappedEvent.sessionId,
|
|
238
238
|
mappedEvent
|
|
239
239
|
);
|
|
240
|
+
if (!metrics && mappedEvent.kind === "lifecycle.before") {
|
|
241
|
+
await startPresenceSession(adapter, mappedEvent.sessionId);
|
|
242
|
+
metrics = await updatePresenceSession(
|
|
243
|
+
adapter,
|
|
244
|
+
mappedEvent.sessionId,
|
|
245
|
+
mappedEvent
|
|
246
|
+
);
|
|
247
|
+
}
|
|
240
248
|
if (mappedEvent.kind === "file.changed" && metrics) {
|
|
241
249
|
mappedEvent = {
|
|
242
250
|
...mappedEvent,
|
|
243
251
|
metadata: {
|
|
244
252
|
...mappedEvent.metadata,
|
|
245
253
|
lines_added: metrics.lines_added,
|
|
246
|
-
lines_deleted: metrics.lines_deleted
|
|
254
|
+
lines_deleted: metrics.lines_deleted,
|
|
255
|
+
task_lines_added: metrics.task_lines_added,
|
|
256
|
+
task_lines_deleted: metrics.task_lines_deleted,
|
|
257
|
+
task_paths: metrics.task_paths
|
|
247
258
|
}
|
|
248
259
|
};
|
|
249
260
|
} else if (mappedEvent.kind === "presence.heartbeat" && metrics) {
|
|
@@ -259,6 +270,7 @@ async function emitCommand(adapter, eventName, input) {
|
|
|
259
270
|
if (mappedEvent.kind === "session.started" || mappedEvent.kind === "session.ended") {
|
|
260
271
|
const publicMetadata = { ...mappedEvent.metadata };
|
|
261
272
|
delete publicMetadata.working_tree_paths;
|
|
273
|
+
delete publicMetadata.task_paths;
|
|
262
274
|
mappedEvent = { ...mappedEvent, metadata: publicMetadata };
|
|
263
275
|
}
|
|
264
276
|
const event = repo ? { ...mappedEvent, repo } : mappedEvent;
|
|
@@ -33,7 +33,10 @@ var canonicalHookEventSchema = z.object({
|
|
|
33
33
|
root: z.string().min(1),
|
|
34
34
|
remote: z.string().min(1).optional(),
|
|
35
35
|
branch: z.string().min(1).optional(),
|
|
36
|
-
commit: z.string().min(1).optional()
|
|
36
|
+
commit: z.string().min(1).optional(),
|
|
37
|
+
defaultBranch: z.string().min(1).optional(),
|
|
38
|
+
baseCommit: z.string().min(1).optional(),
|
|
39
|
+
behindBy: z.number().int().nonnegative().optional()
|
|
37
40
|
}).optional(),
|
|
38
41
|
outcome: z.enum(["success", "failure", "cancelled", "unknown"]).optional(),
|
|
39
42
|
durationMs: z.number().nonnegative().optional(),
|
|
@@ -366,7 +369,10 @@ function toEnvelope(event, options) {
|
|
|
366
369
|
agent_name: event.source,
|
|
367
370
|
hook_kind: event.kind,
|
|
368
371
|
lines_added: typeof event.metadata.lines_added === "number" ? event.metadata.lines_added : void 0,
|
|
369
|
-
lines_deleted: typeof event.metadata.lines_deleted === "number" ? event.metadata.lines_deleted : void 0
|
|
372
|
+
lines_deleted: typeof event.metadata.lines_deleted === "number" ? event.metadata.lines_deleted : void 0,
|
|
373
|
+
task_lines_added: typeof event.metadata.task_lines_added === "number" ? event.metadata.task_lines_added : void 0,
|
|
374
|
+
task_lines_deleted: typeof event.metadata.task_lines_deleted === "number" ? event.metadata.task_lines_deleted : void 0,
|
|
375
|
+
task_paths: Array.isArray(event.metadata.task_paths) ? event.metadata.task_paths : void 0
|
|
370
376
|
} : event.kind === "presence.heartbeat" ? {
|
|
371
377
|
verification: event.metadata.verification,
|
|
372
378
|
sequence: event.metadata.sequence,
|
|
@@ -414,7 +420,10 @@ function toEnvelope(event, options) {
|
|
|
414
420
|
correlation: {
|
|
415
421
|
session_id: event.sessionId,
|
|
416
422
|
branch: event.repo?.branch,
|
|
417
|
-
commit_sha: event.repo?.commit
|
|
423
|
+
commit_sha: event.repo?.commit,
|
|
424
|
+
default_branch: event.repo?.defaultBranch,
|
|
425
|
+
base_commit_sha: event.repo?.baseCommit,
|
|
426
|
+
behind_by: event.repo?.behindBy
|
|
418
427
|
},
|
|
419
428
|
payload
|
|
420
429
|
};
|
|
@@ -584,6 +593,9 @@ async function startPresenceSession(source, sessionId, cwd = process.cwd()) {
|
|
|
584
593
|
sequence: 0,
|
|
585
594
|
linesAdded: 0,
|
|
586
595
|
linesDeleted: 0,
|
|
596
|
+
taskLinesAdded: 0,
|
|
597
|
+
taskLinesDeleted: 0,
|
|
598
|
+
taskPaths: [],
|
|
587
599
|
paths: [],
|
|
588
600
|
modelSeconds: {},
|
|
589
601
|
toolCounts: {},
|
|
@@ -636,6 +648,20 @@ async function updatePresenceSession(source, sessionId, event, cwd = process.cwd
|
|
|
636
648
|
const workingLinesDeleted = optionalCount(
|
|
637
649
|
event.metadata.working_tree_lines_deleted
|
|
638
650
|
);
|
|
651
|
+
if (event.kind === "lifecycle.before") {
|
|
652
|
+
state.taskBaselineLinesAdded = workingLinesAdded;
|
|
653
|
+
state.taskBaselineLinesDeleted = workingLinesDeleted;
|
|
654
|
+
state.taskLinesAdded = 0;
|
|
655
|
+
state.taskLinesDeleted = 0;
|
|
656
|
+
state.taskPaths = [];
|
|
657
|
+
}
|
|
658
|
+
if (event.kind === "file.changed") {
|
|
659
|
+
state.taskLinesAdded += safeCount(event.metadata.lines_added);
|
|
660
|
+
state.taskLinesDeleted += safeCount(event.metadata.lines_deleted);
|
|
661
|
+
if (typeof event.metadata.path === "string") {
|
|
662
|
+
state.taskPaths = [.../* @__PURE__ */ new Set([...state.taskPaths, event.metadata.path])];
|
|
663
|
+
}
|
|
664
|
+
}
|
|
639
665
|
if (workingLinesAdded !== void 0) {
|
|
640
666
|
state.baselineLinesAdded ??= workingLinesAdded;
|
|
641
667
|
const workingDelta = Math.max(
|
|
@@ -652,6 +678,18 @@ async function updatePresenceSession(source, sessionId, event, cwd = process.cwd
|
|
|
652
678
|
);
|
|
653
679
|
state.linesDeleted = isHeartbeat && state.linesDeleted > MAX_SESSION_LINE_COUNT ? workingDelta : Math.max(state.linesDeleted, workingDelta);
|
|
654
680
|
}
|
|
681
|
+
if (event.kind === "file.changed" && workingLinesAdded !== void 0 && state.taskBaselineLinesAdded !== void 0) {
|
|
682
|
+
state.taskLinesAdded = Math.max(
|
|
683
|
+
state.taskLinesAdded,
|
|
684
|
+
Math.max(0, workingLinesAdded - state.taskBaselineLinesAdded)
|
|
685
|
+
);
|
|
686
|
+
}
|
|
687
|
+
if (event.kind === "file.changed" && workingLinesDeleted !== void 0 && state.taskBaselineLinesDeleted !== void 0) {
|
|
688
|
+
state.taskLinesDeleted = Math.max(
|
|
689
|
+
state.taskLinesDeleted,
|
|
690
|
+
Math.max(0, workingLinesDeleted - state.taskBaselineLinesDeleted)
|
|
691
|
+
);
|
|
692
|
+
}
|
|
655
693
|
const paths = [
|
|
656
694
|
...Array.isArray(event.metadata.paths) ? event.metadata.paths.filter(
|
|
657
695
|
(path) => typeof path === "string"
|
|
@@ -730,6 +768,13 @@ async function readPresenceState(path) {
|
|
|
730
768
|
linesDeleted: safeCount(value.linesDeleted),
|
|
731
769
|
baselineLinesAdded: optionalCount(value.baselineLinesAdded),
|
|
732
770
|
baselineLinesDeleted: optionalCount(value.baselineLinesDeleted),
|
|
771
|
+
taskBaselineLinesAdded: optionalCount(value.taskBaselineLinesAdded),
|
|
772
|
+
taskBaselineLinesDeleted: optionalCount(value.taskBaselineLinesDeleted),
|
|
773
|
+
taskLinesAdded: safeCount(value.taskLinesAdded),
|
|
774
|
+
taskLinesDeleted: safeCount(value.taskLinesDeleted),
|
|
775
|
+
taskPaths: Array.isArray(value.taskPaths) ? value.taskPaths.filter(
|
|
776
|
+
(path2) => typeof path2 === "string"
|
|
777
|
+
) : [],
|
|
733
778
|
paths: Array.isArray(value.paths) ? value.paths.filter((path2) => typeof path2 === "string") : [],
|
|
734
779
|
model: typeof value.model === "string" ? canonicalModelName(value.model) : void 0,
|
|
735
780
|
modelSeconds: canonicalModelSeconds(value.modelSeconds),
|
|
@@ -791,6 +836,9 @@ function metricsFromState(state, measuredAt) {
|
|
|
791
836
|
active_seconds: Math.floor(sessionElapsedMs / 1e3),
|
|
792
837
|
lines_added: state.linesAdded,
|
|
793
838
|
lines_deleted: state.linesDeleted,
|
|
839
|
+
task_lines_added: state.taskLinesAdded,
|
|
840
|
+
task_lines_deleted: state.taskLinesDeleted,
|
|
841
|
+
task_paths: state.taskPaths,
|
|
794
842
|
changed_files: state.paths.length,
|
|
795
843
|
model_seconds: state.modelSeconds,
|
|
796
844
|
tool_counts: state.toolCounts,
|
|
@@ -857,6 +905,27 @@ async function git(cwd, args) {
|
|
|
857
905
|
return void 0;
|
|
858
906
|
}
|
|
859
907
|
}
|
|
908
|
+
async function detectDefaultBranch(root) {
|
|
909
|
+
const symbolic = await git(root, [
|
|
910
|
+
"symbolic-ref",
|
|
911
|
+
"--short",
|
|
912
|
+
"refs/remotes/origin/HEAD"
|
|
913
|
+
]);
|
|
914
|
+
const candidates = [
|
|
915
|
+
symbolic?.replace(/^origin\//, ""),
|
|
916
|
+
"main",
|
|
917
|
+
"master"
|
|
918
|
+
].filter((value) => Boolean(value));
|
|
919
|
+
for (const branch of [...new Set(candidates)]) {
|
|
920
|
+
const commit = await git(root, [
|
|
921
|
+
"rev-parse",
|
|
922
|
+
"--verify",
|
|
923
|
+
`refs/remotes/origin/${branch}`
|
|
924
|
+
]);
|
|
925
|
+
if (commit) return { branch, commit };
|
|
926
|
+
}
|
|
927
|
+
return void 0;
|
|
928
|
+
}
|
|
860
929
|
async function detectRepository(cwd = process.cwd()) {
|
|
861
930
|
const root = await git(cwd, ["rev-parse", "--show-toplevel"]);
|
|
862
931
|
if (!root) return void 0;
|
|
@@ -865,11 +934,26 @@ async function detectRepository(cwd = process.cwd()) {
|
|
|
865
934
|
git(root, ["branch", "--show-current"]),
|
|
866
935
|
git(root, ["rev-parse", "HEAD"])
|
|
867
936
|
]);
|
|
937
|
+
const defaultBranch = await detectDefaultBranch(root);
|
|
938
|
+
const baseCommit = branch && commit && defaultBranch ? branch === defaultBranch.branch ? commit : await git(root, [
|
|
939
|
+
"merge-base",
|
|
940
|
+
"HEAD",
|
|
941
|
+
`refs/remotes/origin/${defaultBranch.branch}`
|
|
942
|
+
]) : void 0;
|
|
943
|
+
const behindValue = commit && defaultBranch ? await git(root, [
|
|
944
|
+
"rev-list",
|
|
945
|
+
"--count",
|
|
946
|
+
`HEAD..refs/remotes/origin/${defaultBranch.branch}`
|
|
947
|
+
]) : void 0;
|
|
948
|
+
const behindBy = behindValue !== void 0 && /^\d+$/.test(behindValue) ? Number(behindValue) : void 0;
|
|
868
949
|
return {
|
|
869
950
|
root,
|
|
870
951
|
...remote ? { remote: sanitizeRemote(remote) } : {},
|
|
871
952
|
...branch ? { branch } : {},
|
|
872
|
-
...commit ? { commit } : {}
|
|
953
|
+
...commit ? { commit } : {},
|
|
954
|
+
...defaultBranch ? { defaultBranch: defaultBranch.branch } : {},
|
|
955
|
+
...baseCommit ? { baseCommit } : {},
|
|
956
|
+
...behindBy !== void 0 ? { behindBy } : {}
|
|
873
957
|
};
|
|
874
958
|
}
|
|
875
959
|
async function detectWorkingTreeMetrics(root) {
|
package/dist/cli.js
CHANGED
|
@@ -6,10 +6,10 @@ import {
|
|
|
6
6
|
setupCommand,
|
|
7
7
|
shareProgressCommand,
|
|
8
8
|
statusCommand
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-7UJHKOF6.js";
|
|
10
10
|
import {
|
|
11
11
|
runPresenceHeartbeat
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-WVBSXZG3.js";
|
|
13
13
|
|
|
14
14
|
// src/cli.ts
|
|
15
15
|
var HELP = `wibe-bridge <command>
|
package/dist/codex-hook.js
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -59,6 +59,9 @@ declare const canonicalHookEventSchema: z.ZodObject<{
|
|
|
59
59
|
remote: z.ZodOptional<z.ZodString>;
|
|
60
60
|
branch: z.ZodOptional<z.ZodString>;
|
|
61
61
|
commit: z.ZodOptional<z.ZodString>;
|
|
62
|
+
defaultBranch: z.ZodOptional<z.ZodString>;
|
|
63
|
+
baseCommit: z.ZodOptional<z.ZodString>;
|
|
64
|
+
behindBy: z.ZodOptional<z.ZodNumber>;
|
|
62
65
|
}, z.core.$strip>>;
|
|
63
66
|
outcome: z.ZodOptional<z.ZodEnum<{
|
|
64
67
|
unknown: "unknown";
|
|
@@ -85,6 +88,9 @@ declare function mapClaudeCodeHook(eventName: string, input: unknown): {
|
|
|
85
88
|
remote?: string | undefined;
|
|
86
89
|
branch?: string | undefined;
|
|
87
90
|
commit?: string | undefined;
|
|
91
|
+
defaultBranch?: string | undefined;
|
|
92
|
+
baseCommit?: string | undefined;
|
|
93
|
+
behindBy?: number | undefined;
|
|
88
94
|
} | undefined;
|
|
89
95
|
outcome?: "unknown" | "success" | "failure" | "cancelled" | undefined;
|
|
90
96
|
durationMs?: number | undefined;
|
|
@@ -103,6 +109,9 @@ declare function mapCodexHook(eventName: string, input: unknown): {
|
|
|
103
109
|
remote?: string | undefined;
|
|
104
110
|
branch?: string | undefined;
|
|
105
111
|
commit?: string | undefined;
|
|
112
|
+
defaultBranch?: string | undefined;
|
|
113
|
+
baseCommit?: string | undefined;
|
|
114
|
+
behindBy?: number | undefined;
|
|
106
115
|
} | undefined;
|
|
107
116
|
outcome?: "unknown" | "success" | "failure" | "cancelled" | undefined;
|
|
108
117
|
durationMs?: number | undefined;
|
|
@@ -121,6 +130,9 @@ declare function mapCursorHook(eventName: string, input: unknown): {
|
|
|
121
130
|
remote?: string | undefined;
|
|
122
131
|
branch?: string | undefined;
|
|
123
132
|
commit?: string | undefined;
|
|
133
|
+
defaultBranch?: string | undefined;
|
|
134
|
+
baseCommit?: string | undefined;
|
|
135
|
+
behindBy?: number | undefined;
|
|
124
136
|
} | undefined;
|
|
125
137
|
outcome?: "unknown" | "success" | "failure" | "cancelled" | undefined;
|
|
126
138
|
durationMs?: number | undefined;
|
|
@@ -263,6 +275,9 @@ interface PresenceMetrics {
|
|
|
263
275
|
active_seconds: number;
|
|
264
276
|
lines_added: number;
|
|
265
277
|
lines_deleted: number;
|
|
278
|
+
task_lines_added: number;
|
|
279
|
+
task_lines_deleted: number;
|
|
280
|
+
task_paths: string[];
|
|
266
281
|
changed_files: number;
|
|
267
282
|
model_seconds: Record<string, number>;
|
|
268
283
|
tool_counts: Record<string, number>;
|
|
@@ -289,6 +304,9 @@ interface RepositoryInfo {
|
|
|
289
304
|
remote?: string;
|
|
290
305
|
branch?: string;
|
|
291
306
|
commit?: string;
|
|
307
|
+
defaultBranch?: string;
|
|
308
|
+
baseCommit?: string;
|
|
309
|
+
behindBy?: number;
|
|
292
310
|
}
|
|
293
311
|
interface WorkingTreeMetrics {
|
|
294
312
|
linesAdded: number;
|
package/dist/index.js
CHANGED