@wibeco/bridge 0.2.8 → 0.2.10

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.
@@ -388,7 +388,9 @@ function toEnvelope(event, options) {
388
388
  summary: event.metadata.summary,
389
389
  paths,
390
390
  phase: event.metadata.phase,
391
- confidence: event.metadata.confidence
391
+ confidence: event.metadata.confidence,
392
+ lines_added: typeof event.metadata.lines_added === "number" ? event.metadata.lines_added : void 0,
393
+ lines_deleted: typeof event.metadata.lines_deleted === "number" ? event.metadata.lines_deleted : void 0
392
394
  } : event.kind === "file.changed" ? {
393
395
  paths,
394
396
  tool: event.source,
@@ -626,7 +628,7 @@ var JsonFileOfflineQueue = class {
626
628
  // src/presence.ts
627
629
  import { createHash, randomUUID as randomUUID3 } from "crypto";
628
630
  import { spawn } from "child_process";
629
- import { mkdir as mkdir2, readFile as readFile2, rm, writeFile as writeFile2 } from "fs/promises";
631
+ import { mkdir as mkdir2, readFile as readFile2, readdir, rm, writeFile as writeFile2 } from "fs/promises";
630
632
  import { homedir } from "os";
631
633
  import { join } from "path";
632
634
  var PRESENCE_HEARTBEAT_INTERVAL_MS = 45e3;
@@ -757,9 +759,6 @@ async function updatePresenceSession(source, sessionId, event, cwd = process.cwd
757
759
  ...typeof event.metadata.path === "string" ? [event.metadata.path] : []
758
760
  ];
759
761
  state.paths = [.../* @__PURE__ */ new Set([...state.paths, ...paths])].slice(0, 2e3);
760
- if (event.kind === "lifecycle.after" && state.taskPaths.length === 0) {
761
- state.taskPaths = [...new Set(paths)].slice(0, 2e3);
762
- }
763
762
  const category = toolCategory(event);
764
763
  if (category) {
765
764
  state.toolCounts[category] = (state.toolCounts[category] ?? 0) + 1;
@@ -816,6 +815,35 @@ function presenceStatePath(source, sessionId, cwd = process.cwd()) {
816
815
  const key = createHash("sha256").update(`${source}\0${sessionId ?? ""}\0${cwd}`).digest("hex");
817
816
  return join(presenceDirectory(), `${key}.json`);
818
817
  }
818
+ async function resolveLatestPresenceSession(source, cwd = process.cwd(), maxAgeMs = 5 * 6e4) {
819
+ let names;
820
+ try {
821
+ names = await readdir(presenceDirectory());
822
+ } catch {
823
+ return void 0;
824
+ }
825
+ const now = Date.now();
826
+ let latest;
827
+ for (const name of names) {
828
+ if (!name.endsWith(".json")) continue;
829
+ const path = join(presenceDirectory(), name);
830
+ const state = await readPresenceState(path);
831
+ if (!state?.sessionId || state.source !== source || path !== presenceStatePath(source, state.sessionId, cwd)) {
832
+ continue;
833
+ }
834
+ const lastActivity = Date.parse(state.lastActivityAt);
835
+ if (!Number.isFinite(lastActivity) || lastActivity > now + 6e4 || now - lastActivity > maxAgeMs) {
836
+ continue;
837
+ }
838
+ if (!latest || state.lastActivityAt > latest.lastActivityAt) {
839
+ latest = {
840
+ sessionId: state.sessionId,
841
+ lastActivityAt: state.lastActivityAt
842
+ };
843
+ }
844
+ }
845
+ return latest?.sessionId;
846
+ }
819
847
  function presenceDirectory() {
820
848
  return process.env.WIBE_PRESENCE_DIR ?? join(homedir(), ".wibe", "presence");
821
849
  }
@@ -1418,6 +1446,7 @@ export {
1418
1446
  stopPresenceSession,
1419
1447
  runPresenceHeartbeat,
1420
1448
  presenceStatePath,
1449
+ resolveLatestPresenceSession,
1421
1450
  classifyHeadTransition,
1422
1451
  isObservedPush,
1423
1452
  detectRepository,
@@ -15,10 +15,11 @@ import {
15
15
  observeRepositoryTransitions,
16
16
  pollDeviceToken,
17
17
  requestDeviceAuthorization,
18
+ resolveLatestPresenceSession,
18
19
  startPresenceSession,
19
20
  stopPresenceSession,
20
21
  updatePresenceSession
21
- } from "./chunk-44GDPIWM.js";
22
+ } from "./chunk-FIT6PBBW.js";
22
23
 
23
24
  // src/cli/commands.ts
24
25
  import { access, cp, mkdir, readFile, writeFile } from "fs/promises";
@@ -258,7 +259,7 @@ async function emitCommand(adapter, eventName, input) {
258
259
  task_paths: metrics.task_paths
259
260
  }
260
261
  };
261
- } else if (mappedEvent.kind === "lifecycle.after" && metrics && metrics.task_paths.length > 0) {
262
+ } else if (mappedEvent.kind === "lifecycle.after" && metrics && metrics.task_paths.length > 0 && (metrics.task_lines_added > 0 || metrics.task_lines_deleted > 0)) {
262
263
  mappedEvent = {
263
264
  ...mappedEvent,
264
265
  kind: "response.completed",
@@ -365,14 +366,25 @@ async function shareProgressCommand(options, cwd = process.cwd()) {
365
366
  throw new Error("Progress confidence must be between 0 and 1.");
366
367
  }
367
368
  const repo = await detectRepository(cwd);
369
+ const workingTree = repo ? await detectWorkingTreeMetrics(repo.root) : void 0;
370
+ const sessionId = await resolveLatestPresenceSession(
371
+ projectConfig.adapter,
372
+ cwd
373
+ );
368
374
  const event = createHookEvent({
369
375
  source: projectConfig.adapter,
370
376
  kind: "progress.shared",
377
+ ...sessionId ? { sessionId } : {},
371
378
  metadata: {
372
379
  summary,
373
380
  ...title ? { title } : {},
374
381
  ...options.phase ? { phase: options.phase } : {},
375
- ...options.confidence !== void 0 ? { confidence: options.confidence } : {}
382
+ ...options.confidence !== void 0 ? { confidence: options.confidence } : {},
383
+ ...workingTree ? {
384
+ paths: workingTree.paths,
385
+ lines_added: workingTree.linesAdded,
386
+ lines_deleted: workingTree.linesDeleted
387
+ } : {}
376
388
  },
377
389
  ...repo ? { repo } : {}
378
390
  });
package/dist/cli.js CHANGED
@@ -6,10 +6,10 @@ import {
6
6
  setupCommand,
7
7
  shareProgressCommand,
8
8
  statusCommand
9
- } from "./chunk-G66F67CK.js";
9
+ } from "./chunk-ODX3HMDN.js";
10
10
  import {
11
11
  runPresenceHeartbeat
12
- } from "./chunk-44GDPIWM.js";
12
+ } from "./chunk-FIT6PBBW.js";
13
13
 
14
14
  // src/cli.ts
15
15
  var HELP = `wibe-bridge <command>
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  emitCommand
4
- } from "./chunk-G66F67CK.js";
5
- import "./chunk-44GDPIWM.js";
4
+ } from "./chunk-ODX3HMDN.js";
5
+ import "./chunk-FIT6PBBW.js";
6
6
 
7
7
  // src/codex-hook.ts
8
8
  async function main() {
package/dist/index.d.ts CHANGED
@@ -304,6 +304,7 @@ declare function updatePresenceSession(source: AgentSource, sessionId: string |
304
304
  declare function stopPresenceSession(source: AgentSource, sessionId: string | undefined, cwd?: string): Promise<PresenceMetrics | undefined>;
305
305
  declare function runPresenceHeartbeat(statePath: string, expectedInstanceId: string, emit: (source: AgentSource, eventName: string, payload: Record<string, unknown>) => Promise<unknown>, intervalMs?: number): Promise<void>;
306
306
  declare function presenceStatePath(source: AgentSource, sessionId: string | undefined, cwd?: string): string;
307
+ declare function resolveLatestPresenceSession(source: AgentSource, cwd?: string, maxAgeMs?: number): Promise<string | undefined>;
307
308
 
308
309
  interface RedactionOptions {
309
310
  allowContent?: boolean;
@@ -345,4 +346,4 @@ declare function sanitizeRemote(remote: string): string;
345
346
  declare function normalizeGitHubRepository(value: string): string | undefined;
346
347
  declare function matchesGitHubRepository(remote: string | undefined, expected: string): boolean;
347
348
 
348
- export { type AgentSource, type CanonicalHookEvent, type CredentialStore, type DeviceAuthorization, type DeviceTokenResponse, type FlushResult, type HookEventKind, JsonFileOfflineQueue, MemoryOfflineQueue, type OfflineQueue, PRESENCE_HEARTBEAT_INTERVAL_MS, type PresenceMetrics, type RedactionOptions, type RepositoryInfo, type RepositoryTransition, type SafeValue, SignedBatchClient, type SignedBatchClientOptions, type StoredCredential, SystemCredentialStore, type WorkingTreeMetrics, agentSourceSchema, canonicalHookEventSchema, classifyHeadTransition, createHookEvent, detectRepository, detectWorkingTreeMetrics, deviceAuthorizationSchema, deviceTokenResponseSchema, eventTypeForHook, hookEventKindSchema, isObservedPush, mapClaudeCodeHook, mapCodexHook, mapCursorHook, matchesGitHubRepository, normalizeGitHubRepository, observeRepositoryTransitions, pollDeviceToken, presenceStatePath, redact, requestDeviceAuthorization, runPresenceHeartbeat, safeMetadata, safeValueSchema, sanitizeRemote, startPresenceSession, stopPresenceSession, updatePresenceSession };
349
+ export { type AgentSource, type CanonicalHookEvent, type CredentialStore, type DeviceAuthorization, type DeviceTokenResponse, type FlushResult, type HookEventKind, JsonFileOfflineQueue, MemoryOfflineQueue, type OfflineQueue, PRESENCE_HEARTBEAT_INTERVAL_MS, type PresenceMetrics, type RedactionOptions, type RepositoryInfo, type RepositoryTransition, type SafeValue, SignedBatchClient, type SignedBatchClientOptions, type StoredCredential, SystemCredentialStore, type WorkingTreeMetrics, agentSourceSchema, canonicalHookEventSchema, classifyHeadTransition, createHookEvent, detectRepository, detectWorkingTreeMetrics, deviceAuthorizationSchema, deviceTokenResponseSchema, eventTypeForHook, hookEventKindSchema, isObservedPush, mapClaudeCodeHook, mapCodexHook, mapCursorHook, matchesGitHubRepository, normalizeGitHubRepository, observeRepositoryTransitions, pollDeviceToken, presenceStatePath, redact, requestDeviceAuthorization, resolveLatestPresenceSession, runPresenceHeartbeat, safeMetadata, safeValueSchema, sanitizeRemote, startPresenceSession, stopPresenceSession, updatePresenceSession };
package/dist/index.js CHANGED
@@ -25,6 +25,7 @@ import {
25
25
  presenceStatePath,
26
26
  redact,
27
27
  requestDeviceAuthorization,
28
+ resolveLatestPresenceSession,
28
29
  runPresenceHeartbeat,
29
30
  safeMetadata,
30
31
  safeValueSchema,
@@ -32,7 +33,7 @@ import {
32
33
  startPresenceSession,
33
34
  stopPresenceSession,
34
35
  updatePresenceSession
35
- } from "./chunk-44GDPIWM.js";
36
+ } from "./chunk-FIT6PBBW.js";
36
37
  export {
37
38
  JsonFileOfflineQueue,
38
39
  MemoryOfflineQueue,
@@ -60,6 +61,7 @@ export {
60
61
  presenceStatePath,
61
62
  redact,
62
63
  requestDeviceAuthorization,
64
+ resolveLatestPresenceSession,
63
65
  runPresenceHeartbeat,
64
66
  safeMetadata,
65
67
  safeValueSchema,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wibeco/bridge",
3
- "version": "0.2.8",
3
+ "version": "0.2.10",
4
4
  "description": "Privacy-first live activity bridge for Cursor, Claude Code, and Codex.",
5
5
  "repository": {
6
6
  "type": "git",