@yhong91/vibetime 0.1.69 → 0.1.71

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/bin/vibetime.mjs +995 -293
  2. package/package.json +1 -1
package/bin/vibetime.mjs CHANGED
@@ -884,9 +884,9 @@ var init_esm = __esm({
884
884
 
885
885
  // src/cli.ts
886
886
  import { spawn as spawn2, spawnSync } from "node:child_process";
887
- import { mkdir as mkdir6, open, rm, stat as stat17, writeFile as writeFile5 } from "node:fs/promises";
887
+ import { mkdir as mkdir6, open, rm, stat as stat18, writeFile as writeFile5 } from "node:fs/promises";
888
888
  import os14 from "node:os";
889
- import path26 from "node:path";
889
+ import path27 from "node:path";
890
890
  import { fileURLToPath } from "node:url";
891
891
 
892
892
  // ../shared/src/index.ts
@@ -924,7 +924,7 @@ var TELEMETRY_EVENT_TYPES = [
924
924
  "agent.operation"
925
925
  ];
926
926
  var FILE_ACTIVITY_OPERATIONS = ["read", "search", "create", "write", "edit", "delete"];
927
- var BACKFILL_SOURCE_IDS = ["codex", "claude-code", "claude-cowork", "copilot", "opencode", "pi", "agy", "codebuddy", "qoder", "qoder-cn", "workbuddy", "zcode", "grok-build", "zed", "kimi-code", "cursor", "grok-bot"];
927
+ var BACKFILL_SOURCE_IDS = ["codex", "claude-code", "claude-cowork", "copilot", "opencode", "pi", "agy", "codebuddy", "qoder", "qoder-cn", "workbuddy", "zcode", "grok-build", "zed", "kimi-code", "cursor", "grok-bot", "hermes"];
928
928
  function createWorkspaceId(input) {
929
929
  const basis = input.repoUrl || input.repoRoot || input.projectName || "unknown";
930
930
  return `workspace_${fnv1a(basis)}`;
@@ -1082,9 +1082,9 @@ function removeVolatileHashFields(value) {
1082
1082
  continue;
1083
1083
  }
1084
1084
  if (key === "refs" && isRecord(item)) {
1085
- const refs2 = { ...item };
1086
- delete refs2.payloadHash;
1087
- result[key] = removeVolatileHashFields(refs2);
1085
+ const refs3 = { ...item };
1086
+ delete refs3.payloadHash;
1087
+ result[key] = removeVolatileHashFields(refs3);
1088
1088
  continue;
1089
1089
  }
1090
1090
  result[key] = removeVolatileHashFields(item);
@@ -1747,13 +1747,13 @@ function isPlainObject(value) {
1747
1747
  return value !== null && typeof value === "object" && !Array.isArray(value);
1748
1748
  }
1749
1749
  function stringRefs(value) {
1750
- const refs2 = {};
1750
+ const refs3 = {};
1751
1751
  for (const [key, item] of Object.entries(value || {})) {
1752
1752
  if (typeof item === "string" && item.length > 0) {
1753
- refs2[key] = item;
1753
+ refs3[key] = item;
1754
1754
  }
1755
1755
  }
1756
- return refs2;
1756
+ return refs3;
1757
1757
  }
1758
1758
  function stringOption(value) {
1759
1759
  if (Array.isArray(value)) {
@@ -2047,7 +2047,7 @@ function claudeStyleFileMetrics(tool, input) {
2047
2047
  }
2048
2048
 
2049
2049
  // src/lib/constants.ts
2050
- var PACKAGE_VERSION = true ? "0.1.69" : "0.1.1";
2050
+ var PACKAGE_VERSION = true ? "0.1.71" : "0.1.1";
2051
2051
  var GENERATED_MARKER = "Generated by vibetime.";
2052
2052
  var DEFAULT_API_URL = "http://121.196.224.82:3001";
2053
2053
  var DEFAULT_BACKFILL_BATCH_SIZE = 50;
@@ -2111,7 +2111,7 @@ function withBackfillRefs(event, context) {
2111
2111
  event.type,
2112
2112
  event.refs?.sourceId
2113
2113
  ]);
2114
- const refs2 = {
2114
+ const refs3 = {
2115
2115
  ...stringRefs(event.refs),
2116
2116
  importKey,
2117
2117
  sourcePathHash: context.sourcePathHash,
@@ -2121,12 +2121,12 @@ function withBackfillRefs(event, context) {
2121
2121
  parserVersion: PACKAGE_VERSION
2122
2122
  };
2123
2123
  if (context.options.includeSourcePath) {
2124
- refs2.transcriptPath = context.filePath;
2124
+ refs3.transcriptPath = context.filePath;
2125
2125
  }
2126
2126
  return {
2127
2127
  ...event,
2128
2128
  id: createStableEventId(importKey),
2129
- refs: refs2
2129
+ refs: refs3
2130
2130
  };
2131
2131
  }
2132
2132
  function matchesBackfillFilters(event, options) {
@@ -4186,12 +4186,12 @@ async function parseClaudeCoworkSessionFile(filePath, options) {
4186
4186
  const sessionId = parentSessionId || prefixCoworkId(event.sessionId);
4187
4187
  const turnId = prefixCoworkId(event.turnId);
4188
4188
  const workspaceId = createWorkspaceId({ projectName: project, repoRoot: cwd });
4189
- const refs2 = { ...event.refs };
4189
+ const refs3 = { ...event.refs };
4190
4190
  if (metadata.title) {
4191
- refs2.coworkTitleHash = `sha256:${createStableHash(metadata.title)}`;
4191
+ refs3.coworkTitleHash = `sha256:${createStableHash(metadata.title)}`;
4192
4192
  }
4193
4193
  if (parentSourcePathHash) {
4194
- refs2.sourcePathHash = parentSourcePathHash;
4194
+ refs3.sourcePathHash = parentSourcePathHash;
4195
4195
  }
4196
4196
  const mapped = {
4197
4197
  ...event,
@@ -4203,7 +4203,7 @@ async function parseClaudeCoworkSessionFile(filePath, options) {
4203
4203
  project,
4204
4204
  sessionId,
4205
4205
  turnId,
4206
- refs: refs2
4206
+ refs: refs3
4207
4207
  };
4208
4208
  return rebuildEventIdentity(mapped);
4209
4209
  });
@@ -4936,8 +4936,8 @@ async function codebuddyBackfillFiles(sourceRoot, home, env) {
4936
4936
  }
4937
4937
  const filePath = path9.join(traceDir, entry);
4938
4938
  try {
4939
- const stat18 = await import("node:fs/promises").then((fs) => fs.stat(filePath));
4940
- files.push({ path: filePath, modifiedAt: stat18.mtime.toISOString(), groupId: pidDir.name });
4939
+ const stat19 = await import("node:fs/promises").then((fs) => fs.stat(filePath));
4940
+ files.push({ path: filePath, modifiedAt: stat19.mtime.toISOString(), groupId: pidDir.name });
4941
4941
  } catch {
4942
4942
  }
4943
4943
  }
@@ -9039,9 +9039,695 @@ function createGrokBuildAdapter() {
9039
9039
  };
9040
9040
  }
9041
9041
 
9042
+ // src/adapters/hermes.ts
9043
+ import { readdir as readdir8, stat as stat11 } from "node:fs/promises";
9044
+ import path15 from "node:path";
9045
+ init_fs();
9046
+ var SOURCE = "hermes";
9047
+ var PLUGIN_DIR = ["plugins", "vibetime"];
9048
+ var GENERATED_MARKER3 = "Generated by vibetime.";
9049
+ var HOOK_COMMAND3 = "vibetime hook --agent hermes";
9050
+ function hermesRoot(home, env) {
9051
+ const override = env?.HERMES_HOME;
9052
+ if (override && override.trim()) {
9053
+ return path15.resolve(override);
9054
+ }
9055
+ return path15.join(home, ".hermes");
9056
+ }
9057
+ function hermesPluginDir(home, env) {
9058
+ return path15.join(hermesRoot(home, env), ...PLUGIN_DIR);
9059
+ }
9060
+ function hermesPluginManifestPath(home, env) {
9061
+ return path15.join(hermesPluginDir(home, env), "plugin.yaml");
9062
+ }
9063
+ function hermesPluginInitPath(home, env) {
9064
+ return path15.join(hermesPluginDir(home, env), "__init__.py");
9065
+ }
9066
+ function sourceHash(filePath) {
9067
+ return `sha256:${createStableHash(filePath)}`;
9068
+ }
9069
+ function refs(values) {
9070
+ const out = {};
9071
+ for (const [key, value] of Object.entries(values)) {
9072
+ if (value !== void 0 && value !== "") {
9073
+ out[key] = String(value);
9074
+ }
9075
+ }
9076
+ return out;
9077
+ }
9078
+ function projectFromCwd(cwd, repoRoot) {
9079
+ const basis = repoRoot || cwd;
9080
+ return basis ? path15.basename(basis) || SOURCE : SOURCE;
9081
+ }
9082
+ function isoFromUnix(value) {
9083
+ return timestampFrom(typeof value === "number" ? value : Number(value));
9084
+ }
9085
+ function tableColumns(db, table) {
9086
+ try {
9087
+ const rows = db.prepare(`PRAGMA table_info(${table})`).all();
9088
+ return new Set(rows.map((row) => row.name).filter((name) => Boolean(name)));
9089
+ } catch {
9090
+ return /* @__PURE__ */ new Set();
9091
+ }
9092
+ }
9093
+ function selectExisting(columns, wanted) {
9094
+ return wanted.filter((name) => columns.has(name));
9095
+ }
9096
+ function asRecord(value) {
9097
+ return isPlainObject(value) ? value : {};
9098
+ }
9099
+ function sessionContext(row) {
9100
+ const rawId = stringField(row, "id") || "unknown";
9101
+ const cwd = stringField(row, "cwd");
9102
+ const repoRoot = stringField(row, "git_repo_root");
9103
+ const project = projectFromCwd(cwd, repoRoot);
9104
+ return {
9105
+ rawId,
9106
+ sessionId: `${SOURCE}:${rawId}`,
9107
+ cwd,
9108
+ project,
9109
+ workspaceId: createWorkspaceId({ projectName: project, repoRoot: repoRoot || cwd }),
9110
+ platform: stringField(row, "source"),
9111
+ profileName: stringField(row, "profile_name"),
9112
+ parentSessionId: stringField(row, "parent_session_id"),
9113
+ model: stringField(row, "model"),
9114
+ provider: stringField(row, "billing_provider")
9115
+ };
9116
+ }
9117
+ function makeEvent(event, lineNumber, filePath, options) {
9118
+ const withRefs = withBackfillRefs(event, {
9119
+ filePath,
9120
+ sourcePathHash: sourceHash(filePath),
9121
+ lineNumber,
9122
+ topType: event.type,
9123
+ payloadType: event.refs?.payloadType || event.tool || event.type,
9124
+ options
9125
+ });
9126
+ return validateCanonicalEvent(withRefs).valid ? withRefs : void 0;
9127
+ }
9128
+ function usageMetrics2(row) {
9129
+ const input = numberField(row, "input_tokens") || 0;
9130
+ const output = numberField(row, "output_tokens") || 0;
9131
+ const cacheRead = numberField(row, "cache_read_tokens") || 0;
9132
+ const cacheWrite = numberField(row, "cache_write_tokens") || 0;
9133
+ const reasoning = numberField(row, "reasoning_tokens") || 0;
9134
+ const actualCost = numberField(row, "actual_cost_usd");
9135
+ const estimatedCost = numberField(row, "estimated_cost_usd");
9136
+ const costUsd = actualCost && actualCost > 0 ? actualCost : estimatedCost;
9137
+ return {
9138
+ tokensInput: input || void 0,
9139
+ tokensOutput: output || void 0,
9140
+ tokensCacheReadInput: cacheRead || void 0,
9141
+ tokensCacheCreationInput: cacheWrite || void 0,
9142
+ tokensCachedInput: cacheRead + cacheWrite || void 0,
9143
+ tokensReasoningOutput: reasoning || void 0,
9144
+ tokensTotal: input + output + cacheRead + cacheWrite,
9145
+ modelCalls: numberField(row, "api_call_count") || void 0,
9146
+ costUsd: costUsd && costUsd > 0 ? costUsd : void 0
9147
+ };
9148
+ }
9149
+ function sessionHasWork(row, usageRows) {
9150
+ if (usageRows.some((item) => (numberField(item, "input_tokens") || 0) + (numberField(item, "output_tokens") || 0) > 0)) {
9151
+ return true;
9152
+ }
9153
+ if ((numberField(row, "input_tokens") || 0) + (numberField(row, "output_tokens") || 0) > 0) {
9154
+ return true;
9155
+ }
9156
+ if ((numberField(row, "message_count") || 0) > 0) {
9157
+ return true;
9158
+ }
9159
+ if ((numberField(row, "tool_call_count") || 0) > 0) {
9160
+ return true;
9161
+ }
9162
+ return false;
9163
+ }
9164
+ function parseToolCalls(raw) {
9165
+ let parsed = raw;
9166
+ if (typeof raw === "string" && raw.trim()) {
9167
+ try {
9168
+ parsed = JSON.parse(raw);
9169
+ } catch {
9170
+ return [];
9171
+ }
9172
+ }
9173
+ if (!Array.isArray(parsed)) {
9174
+ return [];
9175
+ }
9176
+ const out = [];
9177
+ for (const item of parsed) {
9178
+ if (!isPlainObject(item)) {
9179
+ continue;
9180
+ }
9181
+ const fn = isPlainObject(item.function) ? item.function : item;
9182
+ const name = stringField(fn, "name") || stringField(item, "name");
9183
+ if (!name) {
9184
+ continue;
9185
+ }
9186
+ let input = {};
9187
+ const args = fn.arguments ?? item.arguments;
9188
+ if (typeof args === "string" && args.trim()) {
9189
+ try {
9190
+ const parsedArgs = JSON.parse(args);
9191
+ if (isPlainObject(parsedArgs)) {
9192
+ input = parsedArgs;
9193
+ }
9194
+ } catch {
9195
+ input = {};
9196
+ }
9197
+ } else if (isPlainObject(args)) {
9198
+ input = args;
9199
+ }
9200
+ out.push({
9201
+ id: stringField(item, "id") || stringField(item, "call_id") || stringField(fn, "id"),
9202
+ name,
9203
+ input
9204
+ });
9205
+ }
9206
+ return out;
9207
+ }
9208
+ function hermesToolAlias(tool) {
9209
+ const normalized = tool.toLowerCase();
9210
+ if (normalized === "write_file") {
9211
+ return "write";
9212
+ }
9213
+ if (normalized === "patch") {
9214
+ return "edit";
9215
+ }
9216
+ if (normalized === "read_file") {
9217
+ return "read";
9218
+ }
9219
+ return tool;
9220
+ }
9221
+ async function sqliteMtime(filePath) {
9222
+ try {
9223
+ const info = await stat11(filePath);
9224
+ let modifiedMs = info.mtimeMs;
9225
+ for (const suffix of ["-wal", "-shm"]) {
9226
+ try {
9227
+ const sidecar = await stat11(`${filePath}${suffix}`);
9228
+ modifiedMs = Math.max(modifiedMs, sidecar.mtimeMs);
9229
+ } catch {
9230
+ }
9231
+ }
9232
+ return new Date(modifiedMs).toISOString();
9233
+ } catch {
9234
+ return void 0;
9235
+ }
9236
+ }
9237
+ async function parseHermesDb(filePath, options) {
9238
+ if (!filePath.endsWith(".db")) {
9239
+ return [];
9240
+ }
9241
+ const { DatabaseSync } = await import("node:sqlite");
9242
+ let db;
9243
+ try {
9244
+ db = new DatabaseSync(filePath, { readOnly: true });
9245
+ } catch {
9246
+ return [];
9247
+ }
9248
+ try {
9249
+ const sessionCols = tableColumns(db, "sessions");
9250
+ if (!sessionCols.has("id") || !sessionCols.has("started_at")) {
9251
+ return [];
9252
+ }
9253
+ const sessionSelect = selectExisting(sessionCols, [
9254
+ "id",
9255
+ "source",
9256
+ "model",
9257
+ "parent_session_id",
9258
+ "started_at",
9259
+ "ended_at",
9260
+ "message_count",
9261
+ "tool_call_count",
9262
+ "input_tokens",
9263
+ "output_tokens",
9264
+ "cache_read_tokens",
9265
+ "cache_write_tokens",
9266
+ "reasoning_tokens",
9267
+ "cwd",
9268
+ "git_repo_root",
9269
+ "billing_provider",
9270
+ "estimated_cost_usd",
9271
+ "actual_cost_usd",
9272
+ "title",
9273
+ "last_activity_at",
9274
+ "profile_name"
9275
+ ]);
9276
+ const sessions = db.prepare(
9277
+ `SELECT ${sessionSelect.join(", ")} FROM sessions WHERE started_at IS NOT NULL ORDER BY started_at, id`
9278
+ ).all().map(asRecord);
9279
+ const usageCols = tableColumns(db, "session_model_usage");
9280
+ const usageBySession = /* @__PURE__ */ new Map();
9281
+ if (usageCols.has("session_id")) {
9282
+ const usageSelect = selectExisting(usageCols, [
9283
+ "session_id",
9284
+ "model",
9285
+ "billing_provider",
9286
+ "billing_base_url",
9287
+ "billing_mode",
9288
+ "task",
9289
+ "api_call_count",
9290
+ "input_tokens",
9291
+ "output_tokens",
9292
+ "cache_read_tokens",
9293
+ "cache_write_tokens",
9294
+ "reasoning_tokens",
9295
+ "estimated_cost_usd",
9296
+ "actual_cost_usd",
9297
+ "first_seen",
9298
+ "last_seen"
9299
+ ]);
9300
+ const usageRows = db.prepare(
9301
+ `SELECT ${usageSelect.join(", ")} FROM session_model_usage`
9302
+ ).all().map(asRecord);
9303
+ for (const row of usageRows) {
9304
+ const sessionId = stringField(row, "session_id");
9305
+ if (!sessionId) {
9306
+ continue;
9307
+ }
9308
+ const list = usageBySession.get(sessionId) || [];
9309
+ list.push(row);
9310
+ usageBySession.set(sessionId, list);
9311
+ }
9312
+ }
9313
+ const messageCols = tableColumns(db, "messages");
9314
+ const messagesBySession = /* @__PURE__ */ new Map();
9315
+ if (messageCols.has("session_id") && messageCols.has("role")) {
9316
+ const messageSelect = selectExisting(messageCols, [
9317
+ "id",
9318
+ "session_id",
9319
+ "role",
9320
+ "content",
9321
+ "tool_calls",
9322
+ "timestamp",
9323
+ "token_count",
9324
+ "active"
9325
+ ]);
9326
+ const activeFilter = messageCols.has("active") ? " WHERE coalesce(active, 1) = 1" : "";
9327
+ const messageRows = db.prepare(
9328
+ `SELECT ${messageSelect.join(", ")} FROM messages${activeFilter} ORDER BY timestamp, id`
9329
+ ).all().map(asRecord);
9330
+ for (const row of messageRows) {
9331
+ const sessionId = stringField(row, "session_id");
9332
+ if (!sessionId) {
9333
+ continue;
9334
+ }
9335
+ const list = messagesBySession.get(sessionId) || [];
9336
+ list.push(row);
9337
+ messagesBySession.set(sessionId, list);
9338
+ }
9339
+ }
9340
+ const events = [];
9341
+ let lineNumber = 0;
9342
+ for (const session of sessions) {
9343
+ const ctx = sessionContext(session);
9344
+ const usageRows = usageBySession.get(ctx.rawId) || [];
9345
+ const messages = messagesBySession.get(ctx.rawId) || [];
9346
+ if (!sessionHasWork(session, usageRows) && messages.length === 0) {
9347
+ continue;
9348
+ }
9349
+ const startedTs = isoFromUnix(session.started_at);
9350
+ if (!startedTs) {
9351
+ continue;
9352
+ }
9353
+ lineNumber += 1;
9354
+ const started = makeEvent({
9355
+ schemaVersion: AGENT_TIME_SCHEMA_VERSION,
9356
+ ts: startedTs,
9357
+ type: "session.started",
9358
+ source: SOURCE,
9359
+ workspaceId: ctx.workspaceId,
9360
+ project: ctx.project,
9361
+ cwd: ctx.cwd,
9362
+ sessionId: ctx.sessionId,
9363
+ parentAgentInstanceId: ctx.parentSessionId ? `${SOURCE}:${ctx.parentSessionId}` : void 0,
9364
+ agent: SOURCE,
9365
+ model: ctx.model,
9366
+ provider: ctx.provider,
9367
+ confidence: "exact",
9368
+ refs: refs({
9369
+ sourceId: `${ctx.rawId}:session`,
9370
+ hermesPlatform: ctx.platform,
9371
+ hermesProfile: ctx.profileName,
9372
+ hermesParentSessionId: ctx.parentSessionId
9373
+ })
9374
+ }, lineNumber, filePath, options);
9375
+ if (started) {
9376
+ events.push(started);
9377
+ }
9378
+ const endedTs = isoFromUnix(session.ended_at) || isoFromUnix(session.last_activity_at);
9379
+ if (endedTs && endedTs !== startedTs) {
9380
+ lineNumber += 1;
9381
+ const ended = makeEvent({
9382
+ schemaVersion: AGENT_TIME_SCHEMA_VERSION,
9383
+ ts: endedTs,
9384
+ type: "session.ended",
9385
+ source: SOURCE,
9386
+ workspaceId: ctx.workspaceId,
9387
+ project: ctx.project,
9388
+ cwd: ctx.cwd,
9389
+ sessionId: ctx.sessionId,
9390
+ parentAgentInstanceId: ctx.parentSessionId ? `${SOURCE}:${ctx.parentSessionId}` : void 0,
9391
+ agent: SOURCE,
9392
+ model: ctx.model,
9393
+ provider: ctx.provider,
9394
+ confidence: "exact",
9395
+ refs: refs({
9396
+ sourceId: `${ctx.rawId}:session:ended`,
9397
+ hermesPlatform: ctx.platform,
9398
+ hermesProfile: ctx.profileName
9399
+ })
9400
+ }, lineNumber, filePath, options);
9401
+ if (ended) {
9402
+ events.push(ended);
9403
+ }
9404
+ }
9405
+ if (usageRows.length > 0) {
9406
+ for (const usage of usageRows) {
9407
+ const ts = isoFromUnix(usage.last_seen) || isoFromUnix(usage.first_seen) || startedTs;
9408
+ lineNumber += 1;
9409
+ const event = makeEvent({
9410
+ schemaVersion: AGENT_TIME_SCHEMA_VERSION,
9411
+ ts,
9412
+ type: "model.usage",
9413
+ source: SOURCE,
9414
+ workspaceId: ctx.workspaceId,
9415
+ project: ctx.project,
9416
+ cwd: ctx.cwd,
9417
+ sessionId: ctx.sessionId,
9418
+ agent: SOURCE,
9419
+ model: stringField(usage, "model") || ctx.model,
9420
+ provider: stringField(usage, "billing_provider") || ctx.provider,
9421
+ success: true,
9422
+ metrics: usageMetrics2(usage),
9423
+ confidence: "exact",
9424
+ refs: refs({
9425
+ sourceId: `${ctx.rawId}:model:${stringField(usage, "model") || "unknown"}:${stringField(usage, "task") || "main"}:${stringField(usage, "billing_provider") || ""}`,
9426
+ hermesPlatform: ctx.platform,
9427
+ hermesProfile: ctx.profileName,
9428
+ hermesTask: stringField(usage, "task"),
9429
+ hermesBillingMode: stringField(usage, "billing_mode")
9430
+ })
9431
+ }, lineNumber, filePath, options);
9432
+ if (event) {
9433
+ events.push(event);
9434
+ }
9435
+ }
9436
+ } else if ((numberField(session, "input_tokens") || 0) + (numberField(session, "output_tokens") || 0) > 0) {
9437
+ lineNumber += 1;
9438
+ const event = makeEvent({
9439
+ schemaVersion: AGENT_TIME_SCHEMA_VERSION,
9440
+ ts: endedTs || startedTs,
9441
+ type: "model.usage",
9442
+ source: SOURCE,
9443
+ workspaceId: ctx.workspaceId,
9444
+ project: ctx.project,
9445
+ cwd: ctx.cwd,
9446
+ sessionId: ctx.sessionId,
9447
+ agent: SOURCE,
9448
+ model: ctx.model,
9449
+ provider: ctx.provider,
9450
+ success: true,
9451
+ metrics: usageMetrics2(session),
9452
+ confidence: "partial",
9453
+ refs: refs({
9454
+ sourceId: `${ctx.rawId}:model:session`,
9455
+ hermesPlatform: ctx.platform,
9456
+ hermesProfile: ctx.profileName
9457
+ })
9458
+ }, lineNumber, filePath, options);
9459
+ if (event) {
9460
+ events.push(event);
9461
+ }
9462
+ }
9463
+ let turnIndex = 0;
9464
+ let activeTurnId;
9465
+ for (const message of messages) {
9466
+ const ts = isoFromUnix(message.timestamp);
9467
+ if (!ts) {
9468
+ continue;
9469
+ }
9470
+ const role = stringField(message, "role");
9471
+ if (role === "user") {
9472
+ turnIndex += 1;
9473
+ activeTurnId = `${ctx.sessionId}:turn:${turnIndex}`;
9474
+ lineNumber += 1;
9475
+ const turnStarted = makeEvent({
9476
+ schemaVersion: AGENT_TIME_SCHEMA_VERSION,
9477
+ ts,
9478
+ type: "turn.started",
9479
+ source: SOURCE,
9480
+ workspaceId: ctx.workspaceId,
9481
+ project: ctx.project,
9482
+ cwd: ctx.cwd,
9483
+ sessionId: ctx.sessionId,
9484
+ turnId: activeTurnId,
9485
+ agent: SOURCE,
9486
+ confidence: "derived",
9487
+ refs: refs({ sourceId: `${ctx.rawId}:turn:${turnIndex}:start` })
9488
+ }, lineNumber, filePath, options);
9489
+ if (turnStarted) {
9490
+ events.push(turnStarted);
9491
+ }
9492
+ const content = stringField(message, "content");
9493
+ lineNumber += 1;
9494
+ const prompt = makeEvent({
9495
+ schemaVersion: AGENT_TIME_SCHEMA_VERSION,
9496
+ ts,
9497
+ type: "prompt.submitted",
9498
+ source: SOURCE,
9499
+ workspaceId: ctx.workspaceId,
9500
+ project: ctx.project,
9501
+ cwd: ctx.cwd,
9502
+ sessionId: ctx.sessionId,
9503
+ turnId: activeTurnId,
9504
+ agent: SOURCE,
9505
+ confidence: "exact",
9506
+ metrics: { promptChars: content?.length, prompts: 1 },
9507
+ refs: refs({ sourceId: `${ctx.rawId}:prompt:${stringField(message, "id") || turnIndex}` })
9508
+ }, lineNumber, filePath, options);
9509
+ if (prompt) {
9510
+ events.push(prompt);
9511
+ }
9512
+ continue;
9513
+ }
9514
+ if (role !== "assistant") {
9515
+ continue;
9516
+ }
9517
+ const tools = parseToolCalls(message.tool_calls);
9518
+ for (const tool of tools) {
9519
+ const toolName = tool.name;
9520
+ const alias = hermesToolAlias(toolName);
9521
+ const toolCallId = tool.id || `${stringField(message, "id") || lineNumber}:${toolName}`;
9522
+ const spanId = `${ctx.sessionId}:tool:${toolCallId}`;
9523
+ const fileActivities = claudeStyleToolFileActivities(alias, tool.input, ts, ctx.cwd);
9524
+ lineNumber += 1;
9525
+ const startedTool = makeEvent({
9526
+ schemaVersion: AGENT_TIME_SCHEMA_VERSION,
9527
+ ts,
9528
+ type: "tool.started",
9529
+ source: SOURCE,
9530
+ workspaceId: ctx.workspaceId,
9531
+ project: ctx.project,
9532
+ cwd: ctx.cwd,
9533
+ sessionId: ctx.sessionId,
9534
+ turnId: activeTurnId,
9535
+ spanId,
9536
+ agent: SOURCE,
9537
+ tool: toolName,
9538
+ confidence: "exact",
9539
+ refs: refs({ sourceId: `${toolCallId}:start` })
9540
+ }, lineNumber, filePath, options);
9541
+ if (startedTool) {
9542
+ events.push(startedTool);
9543
+ }
9544
+ lineNumber += 1;
9545
+ const completedTool = makeEvent({
9546
+ schemaVersion: AGENT_TIME_SCHEMA_VERSION,
9547
+ ts,
9548
+ type: "tool.completed",
9549
+ source: SOURCE,
9550
+ workspaceId: ctx.workspaceId,
9551
+ project: ctx.project,
9552
+ cwd: ctx.cwd,
9553
+ sessionId: ctx.sessionId,
9554
+ turnId: activeTurnId,
9555
+ spanId,
9556
+ agent: SOURCE,
9557
+ tool: toolName,
9558
+ success: true,
9559
+ confidence: "exact",
9560
+ fileActivities: fileActivities.length > 0 ? fileActivities : void 0,
9561
+ refs: refs({ sourceId: `${toolCallId}:completed` })
9562
+ }, lineNumber, filePath, options);
9563
+ if (completedTool) {
9564
+ events.push(completedTool);
9565
+ }
9566
+ }
9567
+ }
9568
+ }
9569
+ return events.sort((a, b) => a.ts.localeCompare(b.ts) || (a.id || "").localeCompare(b.id || ""));
9570
+ } finally {
9571
+ db.close();
9572
+ }
9573
+ }
9574
+ async function collectStateDb(filePath, seen, out) {
9575
+ const resolved = path15.resolve(filePath);
9576
+ if (seen.has(resolved)) {
9577
+ return;
9578
+ }
9579
+ const modifiedAt = await sqliteMtime(resolved);
9580
+ if (!modifiedAt) {
9581
+ return;
9582
+ }
9583
+ seen.add(resolved);
9584
+ out.push({ path: resolved, modifiedAt });
9585
+ }
9586
+ async function collectHermesHome(root, seen, out) {
9587
+ await collectStateDb(path15.join(root, "state.db"), seen, out);
9588
+ const profilesDir = path15.join(root, "profiles");
9589
+ let entries;
9590
+ try {
9591
+ entries = await readdir8(profilesDir, { withFileTypes: true });
9592
+ } catch {
9593
+ return;
9594
+ }
9595
+ for (const entry of entries) {
9596
+ if (entry.isDirectory()) {
9597
+ await collectStateDb(path15.join(profilesDir, entry.name, "state.db"), seen, out);
9598
+ }
9599
+ }
9600
+ }
9601
+ async function hermesBackfillFiles(sourceRoot, home, env = {}) {
9602
+ const seen = /* @__PURE__ */ new Set();
9603
+ const out = [];
9604
+ if (sourceRoot) {
9605
+ if (sourceRoot.endsWith(".db")) {
9606
+ await collectStateDb(sourceRoot, seen, out);
9607
+ return out;
9608
+ }
9609
+ await collectHermesHome(sourceRoot, seen, out);
9610
+ return out;
9611
+ }
9612
+ const primary = hermesRoot(home, env);
9613
+ await collectHermesHome(primary, seen, out);
9614
+ const defaultRoot = path15.join(home, ".hermes");
9615
+ if (path15.resolve(defaultRoot) !== path15.resolve(primary)) {
9616
+ await collectHermesHome(defaultRoot, seen, out);
9617
+ }
9618
+ return out.sort((a, b) => a.path.localeCompare(b.path));
9619
+ }
9620
+ function pluginYaml() {
9621
+ return `# ${GENERATED_MARKER3}
9622
+ name: vibetime
9623
+ version: "1.0.0"
9624
+ description: "VibeTime session sync \u2014 thin trigger that runs local backfill on Hermes lifecycle events."
9625
+ author: VibeTime
9626
+ hooks:
9627
+ - on_session_start
9628
+ - on_session_end
9629
+ - on_session_finalize
9630
+ - post_tool_call
9631
+ `;
9632
+ }
9633
+ function pluginInit() {
9634
+ return `# ${GENERATED_MARKER3}
9635
+ """VibeTime observability plugin for Hermes Agent.
9636
+
9637
+ Thin trigger only: spawn \`vibetime hook --agent hermes\` on session/tool
9638
+ lifecycle events. Token usage is read from state.db by vibetime backfill.
9639
+ """
9640
+ from __future__ import annotations
9641
+
9642
+ import json
9643
+ import os
9644
+ import shutil
9645
+ import subprocess
9646
+ from typing import Any
9647
+
9648
+
9649
+ def _report(payload: dict[str, Any]) -> None:
9650
+ command = shutil.which("vibetime")
9651
+ if not command:
9652
+ return
9653
+ try:
9654
+ subprocess.run(
9655
+ [command, "hook", "--agent", "hermes"],
9656
+ input=json.dumps(payload),
9657
+ text=True,
9658
+ capture_output=True,
9659
+ timeout=10,
9660
+ check=False,
9661
+ env=os.environ.copy(),
9662
+ )
9663
+ except Exception:
9664
+ return
9665
+
9666
+
9667
+ def on_session_start(*, session_id: str = "", **_: Any) -> None:
9668
+ _report({"hook_event_name": "SessionStart", "session_id": session_id})
9669
+
9670
+
9671
+ def on_session_end(*, session_id: str = "", **_: Any) -> None:
9672
+ _report({"hook_event_name": "SessionEnd", "session_id": session_id})
9673
+
9674
+
9675
+ def on_post_tool_call(*, tool_name: str = "", session_id: str = "", **_: Any) -> None:
9676
+ _report({
9677
+ "hook_event_name": "PostToolUse",
9678
+ "tool_name": tool_name or "unknown",
9679
+ "session_id": session_id,
9680
+ })
9681
+
9682
+
9683
+ def register(ctx) -> None:
9684
+ ctx.register_hook("on_session_start", on_session_start)
9685
+ ctx.register_hook("on_session_end", on_session_end)
9686
+ ctx.register_hook("on_session_finalize", on_session_end)
9687
+ ctx.register_hook("post_tool_call", on_post_tool_call)
9688
+ `;
9689
+ }
9690
+ function createHermesAdapter() {
9691
+ return {
9692
+ id: SOURCE,
9693
+ label: "Hermes Agent",
9694
+ agentName: SOURCE,
9695
+ kind: "agent",
9696
+ detectPath(home, env) {
9697
+ return hermesRoot(home, env);
9698
+ },
9699
+ installedPath(home, env) {
9700
+ return hermesPluginManifestPath(home, env);
9701
+ },
9702
+ async isInstalled(home, env) {
9703
+ const manifest = await readTextIfExists(hermesPluginManifestPath(home, env));
9704
+ const init = await readTextIfExists(hermesPluginInitPath(home, env));
9705
+ return Boolean(manifest && init && init.includes(HOOK_COMMAND3));
9706
+ },
9707
+ installEntries(home, env) {
9708
+ return [
9709
+ {
9710
+ kind: "file",
9711
+ path: hermesPluginManifestPath(home, env),
9712
+ content: pluginYaml()
9713
+ },
9714
+ {
9715
+ kind: "file",
9716
+ path: hermesPluginInitPath(home, env),
9717
+ content: pluginInit()
9718
+ }
9719
+ ];
9720
+ },
9721
+ sourcePaths(home, env) {
9722
+ return [path15.join(hermesRoot(home, env), "state.db")];
9723
+ },
9724
+ parseSessionFile: parseHermesDb
9725
+ };
9726
+ }
9727
+
9042
9728
  // src/adapters/kimi-code.ts
9043
9729
  import { readFile as readFile10 } from "node:fs/promises";
9044
- import path15 from "node:path";
9730
+ import path16 from "node:path";
9045
9731
 
9046
9732
  // src/lib/toml-hooks.ts
9047
9733
  init_fs();
@@ -9219,20 +9905,20 @@ function tomlNumberField(body, key) {
9219
9905
  }
9220
9906
 
9221
9907
  // src/adapters/kimi-code.ts
9222
- var HOOK_COMMAND3 = "vibetime hook --agent kimi-code";
9908
+ var HOOK_COMMAND4 = "vibetime hook --agent kimi-code";
9223
9909
  var HOOK_TIMEOUT_SECONDS2 = 10;
9224
9910
  function kimiCodeHome(home, env) {
9225
9911
  const override = env?.KIMI_CODE_HOME || env?.KIMI_HOME;
9226
9912
  if (override && override.trim()) {
9227
- return path15.resolve(override);
9913
+ return path16.resolve(override);
9228
9914
  }
9229
- return path15.join(home, ".kimi-code");
9915
+ return path16.join(home, ".kimi-code");
9230
9916
  }
9231
9917
  function kimiCodeSessionsDir(home, env) {
9232
- return path15.join(kimiCodeHome(home, env), "sessions");
9918
+ return path16.join(kimiCodeHome(home, env), "sessions");
9233
9919
  }
9234
9920
  function kimiCodeConfigPath(home, env) {
9235
- return path15.join(kimiCodeHome(home, env), "config.toml");
9921
+ return path16.join(kimiCodeHome(home, env), "config.toml");
9236
9922
  }
9237
9923
  function kimiHookRules() {
9238
9924
  const events = [
@@ -9248,7 +9934,7 @@ function kimiHookRules() {
9248
9934
  ];
9249
9935
  return events.map((event) => ({
9250
9936
  event,
9251
- command: HOOK_COMMAND3,
9937
+ command: HOOK_COMMAND4,
9252
9938
  timeout: HOOK_TIMEOUT_SECONDS2
9253
9939
  }));
9254
9940
  }
@@ -9308,8 +9994,8 @@ function sessionIdFromWirePath(filePath) {
9308
9994
  return match?.[1];
9309
9995
  }
9310
9996
  async function readSessionState(filePath) {
9311
- const sessionDir = path15.dirname(path15.dirname(path15.dirname(filePath)));
9312
- const statePath = path15.join(sessionDir, "state.json");
9997
+ const sessionDir = path16.dirname(path16.dirname(path16.dirname(filePath)));
9998
+ const statePath = path16.join(sessionDir, "state.json");
9313
9999
  try {
9314
10000
  const text = await readFile10(statePath, "utf8");
9315
10001
  const raw = JSON.parse(text);
@@ -9326,7 +10012,7 @@ async function readSessionState(filePath) {
9326
10012
  }
9327
10013
  }
9328
10014
  async function parseKimiCodeSessionFile(filePath, options) {
9329
- if (path15.basename(filePath) !== "wire.jsonl") {
10015
+ if (path16.basename(filePath) !== "wire.jsonl") {
9330
10016
  return [];
9331
10017
  }
9332
10018
  const text = await readFile10(filePath, "utf8");
@@ -9334,7 +10020,7 @@ async function parseKimiCodeSessionFile(filePath, options) {
9334
10020
  const stateMeta = await readSessionState(filePath);
9335
10021
  let sessionId = stateMeta.sessionId || sessionIdFromWirePath(filePath);
9336
10022
  let cwd = stateMeta.cwd;
9337
- let project = cwd ? path15.basename(cwd) : void 0;
10023
+ let project = cwd ? path16.basename(cwd) : void 0;
9338
10024
  let model;
9339
10025
  let provider;
9340
10026
  let reasoningEffort;
@@ -9380,7 +10066,7 @@ async function parseKimiCodeSessionFile(filePath, options) {
9380
10066
  const disclosedCwd = stringField(disclosure, "cwd");
9381
10067
  if (disclosedCwd) {
9382
10068
  cwd = disclosedCwd;
9383
- project = path15.basename(disclosedCwd);
10069
+ project = path16.basename(disclosedCwd);
9384
10070
  }
9385
10071
  continue;
9386
10072
  }
@@ -9694,7 +10380,7 @@ function createKimiCodeAdapter() {
9694
10380
  return kimiCodeConfigPath(home, env);
9695
10381
  },
9696
10382
  async isInstalled(home, env) {
9697
- return hasTomlHookCommand(kimiCodeConfigPath(home, env), HOOK_COMMAND3);
10383
+ return hasTomlHookCommand(kimiCodeConfigPath(home, env), HOOK_COMMAND4);
9698
10384
  },
9699
10385
  installEntries(home, env) {
9700
10386
  return [{
@@ -9712,7 +10398,7 @@ function createKimiCodeAdapter() {
9712
10398
 
9713
10399
  // src/adapters/opencode.ts
9714
10400
  import os8 from "node:os";
9715
- import path16 from "node:path";
10401
+ import path17 from "node:path";
9716
10402
  async function parseOpenCodeSessionFile(dbPath, options) {
9717
10403
  const { DatabaseSync } = await import("node:sqlite");
9718
10404
  if (!dbPath.endsWith(".db")) {
@@ -9771,7 +10457,7 @@ async function parseOpenCodeSessionFile(dbPath, options) {
9771
10457
  const isSubagent = sessionId !== rawSessionId;
9772
10458
  const sessionEventStart = events.length;
9773
10459
  const cwd = session.directory || session.path || void 0;
9774
- const project = cwd ? path16.basename(cwd) : void 0;
10460
+ const project = cwd ? path17.basename(cwd) : void 0;
9775
10461
  const sessionTs = msToIso(session.time_created);
9776
10462
  events.push(baseOpenCodeEvent({
9777
10463
  ts: sessionTs,
@@ -9879,7 +10565,7 @@ async function parseOpenCodeSessionFile(dbPath, options) {
9879
10565
  const provider = currentProvider;
9880
10566
  const pathObj = objectField(info, "path");
9881
10567
  const assistantCwd = stringField(pathObj, "cwd") || cwd;
9882
- const assistantProject = assistantCwd ? path16.basename(assistantCwd) : project;
10568
+ const assistantProject = assistantCwd ? path17.basename(assistantCwd) : project;
9883
10569
  const completedTs = numberField(objectField(info, "time"), "completed");
9884
10570
  const createdTs = timeCreated;
9885
10571
  const tokens = opencodeUsageFromInfo(info);
@@ -10153,33 +10839,33 @@ function opencodeUsageFromInfo(info) {
10153
10839
  function opencodeConfigDir(home, env) {
10154
10840
  const override = env?.OPENCODE_CONFIG_DIR;
10155
10841
  if (override && override.trim()) {
10156
- return path16.resolve(override);
10842
+ return path17.resolve(override);
10157
10843
  }
10158
10844
  const xdgConfig = env?.XDG_CONFIG_HOME;
10159
10845
  if (xdgConfig && xdgConfig.trim()) {
10160
- return path16.join(path16.resolve(xdgConfig), "opencode");
10846
+ return path17.join(path17.resolve(xdgConfig), "opencode");
10161
10847
  }
10162
- return path16.join(home, ".config", "opencode");
10848
+ return path17.join(home, ".config", "opencode");
10163
10849
  }
10164
10850
  function opencodeDataCandidates(home, env) {
10165
10851
  const xdgData = env?.XDG_DATA_HOME;
10166
- const primary = xdgData && xdgData.trim() ? path16.join(path16.resolve(xdgData), "opencode", "opencode.db") : path16.join(home, ".local", "share", "opencode", "opencode.db");
10167
- return [primary, path16.join(home, ".opencode", "opencode.db")];
10852
+ const primary = xdgData && xdgData.trim() ? path17.join(path17.resolve(xdgData), "opencode", "opencode.db") : path17.join(home, ".local", "share", "opencode", "opencode.db");
10853
+ return [primary, path17.join(home, ".opencode", "opencode.db")];
10168
10854
  }
10169
10855
  async function opencodeBackfillFiles(sourceRoot, home = os8.homedir(), env) {
10170
- const { stat: stat18 } = await import("node:fs/promises");
10856
+ const { stat: stat19 } = await import("node:fs/promises");
10171
10857
  if (sourceRoot) {
10172
10858
  if (!sourceRoot.endsWith(".db")) {
10173
10859
  return [];
10174
10860
  }
10175
- const info = await stat18(sourceRoot).catch(() => null);
10861
+ const info = await stat19(sourceRoot).catch(() => null);
10176
10862
  if (!info) {
10177
10863
  return [];
10178
10864
  }
10179
10865
  return [{ path: sourceRoot, modifiedAt: info.mtime.toISOString() }];
10180
10866
  }
10181
10867
  for (const candidatePath of opencodeDataCandidates(home, env)) {
10182
- const info = await stat18(candidatePath).catch(() => null);
10868
+ const info = await stat19(candidatePath).catch(() => null);
10183
10869
  if (info) {
10184
10870
  return [{ path: candidatePath, modifiedAt: info.mtime.toISOString() }];
10185
10871
  }
@@ -10254,12 +10940,12 @@ function createOpenCodeAdapter() {
10254
10940
  return opencodeConfigDir(home, env);
10255
10941
  },
10256
10942
  installedPath(home, env) {
10257
- return path16.join(opencodeConfigDir(home, env), PLUGIN_PATH);
10943
+ return path17.join(opencodeConfigDir(home, env), PLUGIN_PATH);
10258
10944
  },
10259
10945
  async isInstalled(home, env) {
10260
10946
  try {
10261
10947
  const { pathExists: pathExists2 } = await Promise.resolve().then(() => (init_fs(), fs_exports));
10262
- return await pathExists2(path16.join(opencodeConfigDir(home, env), PLUGIN_PATH)) || await pathExists2(path16.join(".opencode", PLUGIN_PATH));
10948
+ return await pathExists2(path17.join(opencodeConfigDir(home, env), PLUGIN_PATH)) || await pathExists2(path17.join(".opencode", PLUGIN_PATH));
10263
10949
  } catch {
10264
10950
  return false;
10265
10951
  }
@@ -10267,7 +10953,7 @@ function createOpenCodeAdapter() {
10267
10953
  installEntries(home, env) {
10268
10954
  return [{
10269
10955
  kind: "file",
10270
- path: path16.join(opencodeConfigDir(home, env), PLUGIN_PATH),
10956
+ path: path17.join(opencodeConfigDir(home, env), PLUGIN_PATH),
10271
10957
  content: opencodePluginContent()
10272
10958
  }];
10273
10959
  },
@@ -10279,9 +10965,9 @@ function createOpenCodeAdapter() {
10279
10965
  }
10280
10966
 
10281
10967
  // src/adapters/pi.ts
10282
- import { readdir as readdir8, readFile as readFile11, stat as stat11 } from "node:fs/promises";
10968
+ import { readdir as readdir9, readFile as readFile11, stat as stat12 } from "node:fs/promises";
10283
10969
  import os9 from "node:os";
10284
- import path17 from "node:path";
10970
+ import path18 from "node:path";
10285
10971
  init_fs();
10286
10972
  function piHostSessionIdFromBasename(basename) {
10287
10973
  const withoutExt = basename.endsWith(".jsonl") ? basename.slice(0, -".jsonl".length) : basename;
@@ -10296,7 +10982,7 @@ function piHostSessionIdFromBasename(basename) {
10296
10982
  }
10297
10983
  function resolvePiBackfillGroupId(filePath) {
10298
10984
  const normalized = filePath.replaceAll("\\", "/");
10299
- const base = path17.basename(filePath);
10985
+ const base = path18.basename(filePath);
10300
10986
  const nest = normalized.match(/([^/]+)\/[^/]+\/run-\d+\/session\.jsonl$/);
10301
10987
  if (nest) {
10302
10988
  return piHostSessionIdFromBasename(nest[1]);
@@ -10308,8 +10994,8 @@ function resolvePiBackfillGroupId(filePath) {
10308
10994
  }
10309
10995
  function parsePiSubagentLink(filePath, headerParentSession) {
10310
10996
  if (headerParentSession) {
10311
- const parentFile = path17.isAbsolute(headerParentSession) ? headerParentSession : void 0;
10312
- const parentSessionId2 = parentFile ? path17.basename(parentFile, ".jsonl") : headerParentSession;
10997
+ const parentFile = path18.isAbsolute(headerParentSession) ? headerParentSession : void 0;
10998
+ const parentSessionId2 = parentFile ? path18.basename(parentFile, ".jsonl") : headerParentSession;
10313
10999
  return { parentSessionId: parentSessionId2, parentSessionFile: parentFile, explicit: true };
10314
11000
  }
10315
11001
  const normalized = filePath.replaceAll("\\", "/");
@@ -10322,8 +11008,8 @@ function parsePiSubagentLink(filePath, headerParentSession) {
10322
11008
  return void 0;
10323
11009
  }
10324
11010
  const parentSessionId = parentBasename.endsWith(".jsonl") ? parentBasename.slice(0, -".jsonl".length) : parentBasename;
10325
- const parentDir = path17.dirname(path17.dirname(path17.dirname(filePath)));
10326
- const parentSessionFile = path17.join(path17.dirname(parentDir), `${parentBasename}.jsonl`);
11011
+ const parentDir = path18.dirname(path18.dirname(path18.dirname(filePath)));
11012
+ const parentSessionFile = path18.join(path18.dirname(parentDir), `${parentBasename}.jsonl`);
10327
11013
  return { parentSessionId, parentSessionFile, explicit: false };
10328
11014
  }
10329
11015
  async function resolveParentContext(link, options) {
@@ -10335,7 +11021,7 @@ async function resolveParentContext(link, options) {
10335
11021
  if (raw) {
10336
11022
  const id = stringField(raw, "id");
10337
11023
  const cwd = stringField(raw, "cwd");
10338
- const project = cwd ? path17.basename(cwd) : void 0;
11024
+ const project = cwd ? path18.basename(cwd) : void 0;
10339
11025
  if (id || cwd || project) {
10340
11026
  return { sessionId: id, cwd, project };
10341
11027
  }
@@ -10416,7 +11102,7 @@ async function parsePiSessionFile(filePath, options) {
10416
11102
  sessionId = stringField(raw, "id") || state.sessionId;
10417
11103
  state.sessionId = sessionId || state.sessionId;
10418
11104
  cwd = stringField(raw, "cwd") || cwd;
10419
- project = cwd ? path17.basename(cwd) : project;
11105
+ project = cwd ? path18.basename(cwd) : project;
10420
11106
  headerParentSession = stringField(raw, "parentSession") || headerParentSession;
10421
11107
  continue;
10422
11108
  }
@@ -10691,17 +11377,17 @@ async function parsePiWorkflowRunFile(filePath, options) {
10691
11377
  return state.events.filter((event) => matchesBackfillFilters(event, options));
10692
11378
  }
10693
11379
  async function findPiSessionFileById(sessionId, options) {
10694
- const sessionsDir = piSessionDir(path17.resolve(stringOption(options.home) || os9.homedir()));
11380
+ const sessionsDir = piSessionDir(path18.resolve(stringOption(options.home) || os9.homedir()));
10695
11381
  try {
10696
- const projectDirs = await readdir8(sessionsDir, { withFileTypes: true });
11382
+ const projectDirs = await readdir9(sessionsDir, { withFileTypes: true });
10697
11383
  for (const dir of projectDirs) {
10698
11384
  if (!dir.isDirectory()) {
10699
11385
  continue;
10700
11386
  }
10701
- const names = await readdir8(path17.join(sessionsDir, dir.name));
11387
+ const names = await readdir9(path18.join(sessionsDir, dir.name));
10702
11388
  const hit = names.find((name) => name.endsWith(`_${sessionId}.jsonl`));
10703
11389
  if (hit) {
10704
- return path17.join(sessionsDir, dir.name, hit);
11390
+ return path18.join(sessionsDir, dir.name, hit);
10705
11391
  }
10706
11392
  }
10707
11393
  } catch {
@@ -10943,19 +11629,19 @@ export default function (pi: ExtensionAPI) {
10943
11629
  function piAgentDir(home, env) {
10944
11630
  const override = env?.PI_CODING_AGENT_DIR;
10945
11631
  if (override && override.trim()) {
10946
- return path17.resolve(override);
11632
+ return path18.resolve(override);
10947
11633
  }
10948
- return path17.join(home, ".pi", "agent");
11634
+ return path18.join(home, ".pi", "agent");
10949
11635
  }
10950
11636
  function piSessionDir(home, env) {
10951
11637
  const override = env?.PI_CODING_AGENT_SESSION_DIR;
10952
11638
  if (override && override.trim()) {
10953
- return path17.resolve(override);
11639
+ return path18.resolve(override);
10954
11640
  }
10955
- return path17.join(piAgentDir(home, env), "sessions");
11641
+ return path18.join(piAgentDir(home, env), "sessions");
10956
11642
  }
10957
11643
  function piWorkflowProjectsDir(home) {
10958
- return path17.join(home, ".pi", "workflows", "projects");
11644
+ return path18.join(home, ".pi", "workflows", "projects");
10959
11645
  }
10960
11646
  async function workflowRunGroupId(filePath) {
10961
11647
  try {
@@ -10975,7 +11661,7 @@ async function piBackfillFiles(sourceRoot, home = os9.homedir(), env) {
10975
11661
  ]);
10976
11662
  const files = lists.flat().sort();
10977
11663
  return Promise.all(files.map(async (filePath) => {
10978
- const info = await stat11(filePath);
11664
+ const info = await stat12(filePath);
10979
11665
  let groupId = resolvePiBackfillGroupId(filePath);
10980
11666
  if (!groupId && filePath.endsWith(".json")) {
10981
11667
  groupId = await workflowRunGroupId(filePath);
@@ -10997,12 +11683,12 @@ function createPiAdapter() {
10997
11683
  return piAgentDir(home, env);
10998
11684
  },
10999
11685
  installedPath(home, env) {
11000
- return path17.join(piAgentDir(home, env), "extensions", "vibetime.ts");
11686
+ return path18.join(piAgentDir(home, env), "extensions", "vibetime.ts");
11001
11687
  },
11002
11688
  async isInstalled(home, env) {
11003
11689
  try {
11004
11690
  const { pathExists: pathExists2 } = await Promise.resolve().then(() => (init_fs(), fs_exports));
11005
- return await pathExists2(path17.join(piAgentDir(home, env), "extensions", "vibetime.ts"));
11691
+ return await pathExists2(path18.join(piAgentDir(home, env), "extensions", "vibetime.ts"));
11006
11692
  } catch {
11007
11693
  return false;
11008
11694
  }
@@ -11010,7 +11696,7 @@ function createPiAdapter() {
11010
11696
  installEntries(home, env) {
11011
11697
  return [{
11012
11698
  kind: "file",
11013
- path: path17.join(piAgentDir(home, env), "extensions", "vibetime.ts"),
11699
+ path: path18.join(piAgentDir(home, env), "extensions", "vibetime.ts"),
11014
11700
  content: piExtensionContent()
11015
11701
  }];
11016
11702
  },
@@ -11022,14 +11708,14 @@ function createPiAdapter() {
11022
11708
  }
11023
11709
 
11024
11710
  // src/adapters/qoder-cn.ts
11025
- import { readdir as readdir9, readFile as readFile12, stat as stat12 } from "node:fs/promises";
11711
+ import { readdir as readdir10, readFile as readFile12, stat as stat13 } from "node:fs/promises";
11026
11712
  import os11 from "node:os";
11027
- import path19 from "node:path";
11713
+ import path20 from "node:path";
11028
11714
 
11029
11715
  // src/adapters/qoder-local-db.ts
11030
11716
  import { access } from "node:fs/promises";
11031
11717
  import os10 from "node:os";
11032
- import path18 from "node:path";
11718
+ import path19 from "node:path";
11033
11719
  function takeQoderDbModelCall(calls, requestId, blockStart) {
11034
11720
  if (requestId) {
11035
11721
  const call = calls.byRequestId.get(requestId)?.shift();
@@ -11048,12 +11734,12 @@ function takeQoderDbModelCall(calls, requestId, blockStart) {
11048
11734
  }
11049
11735
  function appDataRoot(appDirName, home = os10.homedir()) {
11050
11736
  if (process.platform === "darwin") {
11051
- return path18.join(home, "Library", "Application Support", appDirName);
11737
+ return path19.join(home, "Library", "Application Support", appDirName);
11052
11738
  }
11053
11739
  if (process.platform === "win32") {
11054
- return path18.join(process.env.APPDATA || path18.join(home, "AppData", "Roaming"), appDirName);
11740
+ return path19.join(process.env.APPDATA || path19.join(home, "AppData", "Roaming"), appDirName);
11055
11741
  }
11056
- return path18.join(home, ".config", appDirName);
11742
+ return path19.join(home, ".config", appDirName);
11057
11743
  }
11058
11744
  function qoderLocalDbCandidates(appDirName) {
11059
11745
  const candidates = [];
@@ -11063,8 +11749,8 @@ function qoderLocalDbCandidates(appDirName) {
11063
11749
  }
11064
11750
  const configRoot = appDataRoot(appDirName);
11065
11751
  candidates.push(
11066
- path18.join(configRoot, "SharedClientCache", "cache", "db", "local.db"),
11067
- path18.join(configRoot, "SharedClientCache", "db", "local.db")
11752
+ path19.join(configRoot, "SharedClientCache", "cache", "db", "local.db"),
11753
+ path19.join(configRoot, "SharedClientCache", "db", "local.db")
11068
11754
  );
11069
11755
  return candidates;
11070
11756
  }
@@ -11073,7 +11759,7 @@ async function loadQoderIdeModelCatalog(appDirName, home) {
11073
11759
  try {
11074
11760
  const { DatabaseSync } = await import("node:sqlite");
11075
11761
  const db = new DatabaseSync(
11076
- path18.join(appDataRoot(appDirName, home), "User", "globalStorage", "state.vscdb"),
11762
+ path19.join(appDataRoot(appDirName, home), "User", "globalStorage", "state.vscdb"),
11077
11763
  { readOnly: true }
11078
11764
  );
11079
11765
  try {
@@ -11215,7 +11901,7 @@ function resolveSessionPreferredModel(db, sessionId, modelMap) {
11215
11901
 
11216
11902
  // src/adapters/qoder-cn.ts
11217
11903
  function parseQoderCnPaths(filePath) {
11218
- const parts = filePath.split(path19.sep);
11904
+ const parts = filePath.split(path20.sep);
11219
11905
  const subagentsIdx = parts.lastIndexOf("subagents");
11220
11906
  let sessionId = "";
11221
11907
  let projectName = "";
@@ -11225,17 +11911,17 @@ function parseQoderCnPaths(filePath) {
11225
11911
  sessionId = parts[subagentsIdx - 1];
11226
11912
  projectName = parts[subagentsIdx - 2];
11227
11913
  const projectsIdx = parts.lastIndexOf("projects");
11228
- configDir2 = parts.slice(0, projectsIdx).join(path19.sep);
11229
- mainTranscriptPath = [...parts.slice(0, subagentsIdx - 1), `${sessionId}.jsonl`].join(path19.sep);
11914
+ configDir2 = parts.slice(0, projectsIdx).join(path20.sep);
11915
+ mainTranscriptPath = [...parts.slice(0, subagentsIdx - 1), `${sessionId}.jsonl`].join(path20.sep);
11230
11916
  } else {
11231
11917
  const filename = parts.at(-1) || "";
11232
- sessionId = path19.basename(filename, ".jsonl");
11918
+ sessionId = path20.basename(filename, ".jsonl");
11233
11919
  projectName = parts.at(-2) || "";
11234
11920
  if (projectName === "transcript") {
11235
11921
  projectName = parts.at(-3) || "";
11236
11922
  }
11237
11923
  const projectsIdx = parts.lastIndexOf("projects");
11238
- configDir2 = parts.slice(0, projectsIdx).join(path19.sep);
11924
+ configDir2 = parts.slice(0, projectsIdx).join(path20.sep);
11239
11925
  }
11240
11926
  return { configDir: configDir2, projectName, sessionId, mainTranscriptPath };
11241
11927
  }
@@ -11274,19 +11960,25 @@ async function parseModelNamesFromDynamicTexts(dynamicTextsPath) {
11274
11960
  }
11275
11961
  }
11276
11962
  async function loadQoderCnModelNames(configDir2, home) {
11277
- const map = await parseModelNamesFromDynamicTexts(path19.join(configDir2, ".auth", "dynamic-texts.json"));
11278
- const siblingConfigDir = configDir2.replace(/\.qoder-cn$/, ".qoder");
11279
- if (siblingConfigDir !== configDir2) {
11280
- const siblingMap = await parseModelNamesFromDynamicTexts(path19.join(siblingConfigDir, ".auth", "dynamic-texts.json"));
11281
- for (const [key, val] of Object.entries(siblingMap)) {
11963
+ const map = {};
11964
+ for (const appDirName of ["QoderCN", "Qoder"]) {
11965
+ const ideMap = await loadQoderIdeModelCatalog(appDirName, home);
11966
+ for (const [key, val] of Object.entries(ideMap)) {
11282
11967
  if (!(key in map)) {
11283
11968
  map[key] = val;
11284
11969
  }
11285
11970
  }
11286
11971
  }
11287
- for (const appDirName of ["QoderCN", "Qoder"]) {
11288
- const ideMap = await loadQoderIdeModelCatalog(appDirName, home);
11289
- for (const [key, val] of Object.entries(ideMap)) {
11972
+ const textsMap = await parseModelNamesFromDynamicTexts(path20.join(configDir2, ".auth", "dynamic-texts.json"));
11973
+ for (const [key, val] of Object.entries(textsMap)) {
11974
+ if (!(key in map)) {
11975
+ map[key] = val;
11976
+ }
11977
+ }
11978
+ const siblingConfigDir = configDir2.replace(/\.qoder-cn$/, ".qoder");
11979
+ if (siblingConfigDir !== configDir2) {
11980
+ const siblingMap = await parseModelNamesFromDynamicTexts(path20.join(siblingConfigDir, ".auth", "dynamic-texts.json"));
11981
+ for (const [key, val] of Object.entries(siblingMap)) {
11290
11982
  if (!(key in map)) {
11291
11983
  map[key] = val;
11292
11984
  }
@@ -11296,15 +11988,15 @@ async function loadQoderCnModelNames(configDir2, home) {
11296
11988
  }
11297
11989
  async function loadQoderCnSegmentModelCalls(filePath, isSubagentSession, modelMap) {
11298
11990
  const { configDir: configDir2, projectName, sessionId } = parseQoderCnPaths(filePath);
11299
- const segmentsPath = path19.join(configDir2, "logs", "sessions", projectName, sessionId, "segments");
11991
+ const segmentsPath = path20.join(configDir2, "logs", "sessions", projectName, sessionId, "segments");
11300
11992
  const modelCalls = [];
11301
11993
  try {
11302
- const files = await readdir9(segmentsPath);
11994
+ const files = await readdir10(segmentsPath);
11303
11995
  for (const file of files) {
11304
11996
  if (!file.endsWith(".jsonl")) {
11305
11997
  continue;
11306
11998
  }
11307
- const content = await readFile12(path19.join(segmentsPath, file), "utf8");
11999
+ const content = await readFile12(path20.join(segmentsPath, file), "utf8");
11308
12000
  let currentTurnIsSubagent = false;
11309
12001
  for (const line of content.split("\n").filter(Boolean)) {
11310
12002
  const raw = parseJsonLine(line);
@@ -11349,7 +12041,7 @@ async function parseQoderCnSessionFile(filePath, options) {
11349
12041
  let cwd;
11350
12042
  let project = projectContext.project;
11351
12043
  let model;
11352
- const home = path19.resolve(stringOption(options.home) || os11.homedir());
12044
+ const home = path20.resolve(stringOption(options.home) || os11.homedir());
11353
12045
  const modelMap = await loadQoderCnModelNames(configDir2, home);
11354
12046
  const isSubagentSession = filePath.includes("subagents");
11355
12047
  const segmentModelCalls = await loadQoderCnSegmentModelCalls(filePath, isSubagentSession, modelMap);
@@ -11384,7 +12076,7 @@ async function parseQoderCnSessionFile(filePath, options) {
11384
12076
  sessionId = stringField(raw, "sessionId") || sessionId;
11385
12077
  state.sessionId = sessionId;
11386
12078
  cwd = stringField(raw, "cwd") || cwd;
11387
- project = projectContext.project || (cwd ? path19.basename(cwd) : project || await qoderCnProjectFromFilePath(filePath, options));
12079
+ project = projectContext.project || (cwd ? path20.basename(cwd) : project || await qoderCnProjectFromFilePath(filePath, options));
11388
12080
  if (!ts) {
11389
12081
  continue;
11390
12082
  }
@@ -11720,7 +12412,7 @@ async function parseQoderCnSessionFile(filePath, options) {
11720
12412
  }
11721
12413
  dbModelCalls ??= await loadQoderDbModelCalls("QoderCN", parsedPaths.sessionId, modelMap);
11722
12414
  if (dbModelCalls.rootSessionId) {
11723
- const parentPath = path19.join(path19.dirname(filePath), `${dbModelCalls.rootSessionId}.jsonl`);
12415
+ const parentPath = path20.join(path20.dirname(filePath), `${dbModelCalls.rootSessionId}.jsonl`);
11724
12416
  const parentSourcePathHash = `sha256:${createStableHash(parentPath)}`;
11725
12417
  return withoutSubagentTurnEvents(validEvents).map((event) => rebuildEventIdentity3({
11726
12418
  ...event,
@@ -11873,28 +12565,28 @@ function extractQoderAttachedPrompt(content) {
11873
12565
  }
11874
12566
  async function qoderCnProjectContextFromLines(filePath, lines, options, configDir2) {
11875
12567
  const { projectName: projectDir, sessionId } = parseQoderCnPaths(filePath);
11876
- const isSubagent = filePath.includes(`${path19.sep}subagents${path19.sep}`);
12568
+ const isSubagent = filePath.includes(`${path20.sep}subagents${path20.sep}`);
11877
12569
  const inherited = isSubagent ? await readPersistedSessionContextFromOptions(options, sessionId) : void 0;
11878
12570
  let cwds = [];
11879
12571
  for (const line of lines) {
11880
12572
  const raw = parseJsonLine(line);
11881
12573
  const cwd = raw ? stringField(raw, "cwd") : void 0;
11882
- if (cwd && path19.isAbsolute(cwd)) {
12574
+ if (cwd && path20.isAbsolute(cwd)) {
11883
12575
  cwds.push(cwd);
11884
12576
  }
11885
12577
  }
11886
12578
  if (isSubagent) {
11887
- if (inherited?.cwd && path19.isAbsolute(inherited.cwd)) {
12579
+ if (inherited?.cwd && path20.isAbsolute(inherited.cwd)) {
11888
12580
  cwds = [inherited.cwd];
11889
12581
  } else {
11890
- const parentSessionPath = path19.join(configDir2, "projects", projectDir, `${sessionId}.jsonl`);
12582
+ const parentSessionPath = path20.join(configDir2, "projects", projectDir, `${sessionId}.jsonl`);
11891
12583
  try {
11892
12584
  const parentText = await readFile12(parentSessionPath, "utf8");
11893
12585
  const parentCwds = [];
11894
12586
  for (const line of parentText.split("\n").filter(Boolean)) {
11895
12587
  const raw = parseJsonLine(line);
11896
12588
  const cwd = raw ? stringField(raw, "cwd") : void 0;
11897
- if (cwd && path19.isAbsolute(cwd)) {
12589
+ if (cwd && path20.isAbsolute(cwd)) {
11898
12590
  parentCwds.push(cwd);
11899
12591
  }
11900
12592
  }
@@ -11906,7 +12598,7 @@ async function qoderCnProjectContextFromLines(filePath, lines, options, configDi
11906
12598
  }
11907
12599
  }
11908
12600
  const root = await gitRootFromCwds2(cwds) || qoderCnProjectRootFromCwds(projectDir, cwds);
11909
- const project = inherited?.project || (cwds.length > 0 ? path19.basename(cwds[0]) : root ? path19.basename(root) : await qoderCnProjectFromFilePath(filePath, options));
12601
+ const project = inherited?.project || (cwds.length > 0 ? path20.basename(cwds[0]) : root ? path20.basename(root) : await qoderCnProjectFromFilePath(filePath, options));
11910
12602
  return {
11911
12603
  project,
11912
12604
  workspaceId: createWorkspaceId({ projectName: project, repoRoot: root })
@@ -11915,15 +12607,15 @@ async function qoderCnProjectContextFromLines(filePath, lines, options, configDi
11915
12607
  async function gitRootFromCwds2(cwds) {
11916
12608
  const seen = /* @__PURE__ */ new Set();
11917
12609
  for (const cwd of cwds) {
11918
- let current = path19.resolve(cwd);
12610
+ let current = path20.resolve(cwd);
11919
12611
  while (!seen.has(current)) {
11920
12612
  seen.add(current);
11921
12613
  try {
11922
- await stat12(path19.join(current, ".git"));
12614
+ await stat13(path20.join(current, ".git"));
11923
12615
  return current;
11924
12616
  } catch {
11925
12617
  }
11926
- const parent = path19.dirname(current);
12618
+ const parent = path20.dirname(current);
11927
12619
  if (parent === current) {
11928
12620
  break;
11929
12621
  }
@@ -11934,12 +12626,12 @@ async function gitRootFromCwds2(cwds) {
11934
12626
  }
11935
12627
  function qoderCnProjectRootFromCwds(projectDir, cwds) {
11936
12628
  for (const cwd of cwds) {
11937
- let current = path19.resolve(cwd);
12629
+ let current = path20.resolve(cwd);
11938
12630
  while (true) {
11939
12631
  if (encodeQoderCnProjectPath(current) === projectDir) {
11940
12632
  return current;
11941
12633
  }
11942
- const parent = path19.dirname(current);
12634
+ const parent = path20.dirname(current);
11943
12635
  if (parent === current) {
11944
12636
  break;
11945
12637
  }
@@ -11949,14 +12641,14 @@ function qoderCnProjectRootFromCwds(projectDir, cwds) {
11949
12641
  return void 0;
11950
12642
  }
11951
12643
  function encodeQoderCnProjectPath(value) {
11952
- return path19.resolve(value).split(path19.sep).join("-").replaceAll("_", "-");
12644
+ return path20.resolve(value).split(path20.sep).join("-").replaceAll("_", "-");
11953
12645
  }
11954
12646
  async function qoderCnProjectFromFilePath(filePath, options) {
11955
- const projectDir = path19.basename(path19.dirname(filePath));
11956
- const home = options ? path19.resolve(stringOption(options.home) || os11.homedir()) : os11.homedir();
12647
+ const projectDir = path20.basename(path20.dirname(filePath));
12648
+ const home = options ? path20.resolve(stringOption(options.home) || os11.homedir()) : os11.homedir();
11957
12649
  const resolved = await resolveQoderCnProjectPath(projectDir, home);
11958
12650
  if (resolved) {
11959
- return path19.basename(resolved);
12651
+ return path20.basename(resolved);
11960
12652
  }
11961
12653
  const homePrefix = `${encodeQoderCnProjectPath(home)}-`;
11962
12654
  if (projectDir.startsWith(homePrefix)) {
@@ -11976,12 +12668,12 @@ async function resolveQoderCnProjectPath(projectDir, home) {
11976
12668
  while (projectDir.startsWith(`${currentEncoded}-`)) {
11977
12669
  let matchedChild;
11978
12670
  try {
11979
- const entries = await readdir9(current, { withFileTypes: true });
12671
+ const entries = await readdir10(current, { withFileTypes: true });
11980
12672
  for (const entry of entries) {
11981
12673
  if (!entry.isDirectory()) {
11982
12674
  continue;
11983
12675
  }
11984
- const candidate = path19.join(current, entry.name);
12676
+ const candidate = path20.join(current, entry.name);
11985
12677
  const encoded = encodeQoderCnProjectPath(candidate);
11986
12678
  if (encoded === projectDir) {
11987
12679
  return candidate;
@@ -12026,9 +12718,9 @@ function hookConfig6() {
12026
12718
  function qoderCnConfigDir(home, env) {
12027
12719
  const override = env?.QODER_CN_CONFIG_DIR;
12028
12720
  if (override && override.trim()) {
12029
- return path19.resolve(override);
12721
+ return path20.resolve(override);
12030
12722
  }
12031
- return path19.join(home, ".qoder-cn");
12723
+ return path20.join(home, ".qoder-cn");
12032
12724
  }
12033
12725
  function createQoderCnAdapter() {
12034
12726
  return {
@@ -12040,27 +12732,27 @@ function createQoderCnAdapter() {
12040
12732
  return qoderCnConfigDir(home, env);
12041
12733
  },
12042
12734
  installedPath(home, env) {
12043
- return path19.join(qoderCnConfigDir(home, env), "settings.json");
12735
+ return path20.join(qoderCnConfigDir(home, env), "settings.json");
12044
12736
  },
12045
12737
  async isInstalled(home, env) {
12046
12738
  return isHooksJsonInstalled(
12047
- path19.join(qoderCnConfigDir(home, env), "settings.json"),
12739
+ path20.join(qoderCnConfigDir(home, env), "settings.json"),
12048
12740
  "vibetime hook --agent qoder-cn"
12049
12741
  );
12050
12742
  },
12051
12743
  installEntries(home, env) {
12052
12744
  return [{
12053
12745
  kind: "hooks-json",
12054
- path: path19.join(qoderCnConfigDir(home, env), "settings.json"),
12746
+ path: path20.join(qoderCnConfigDir(home, env), "settings.json"),
12055
12747
  content: hookConfig6()
12056
12748
  }];
12057
12749
  },
12058
12750
  sourcePaths(home, env) {
12059
12751
  const base = qoderCnConfigDir(home, env);
12060
12752
  return [
12061
- path19.join(base, "projects"),
12062
- path19.join(base, ".qoder.json"),
12063
- path19.join(home, ".qoder.json")
12753
+ path20.join(base, "projects"),
12754
+ path20.join(base, ".qoder.json"),
12755
+ path20.join(home, ".qoder.json")
12064
12756
  ];
12065
12757
  },
12066
12758
  parseSessionFile: parseQoderCnSessionFile
@@ -12069,11 +12761,11 @@ function createQoderCnAdapter() {
12069
12761
 
12070
12762
  // src/adapters/qoder.ts
12071
12763
  import { existsSync } from "node:fs";
12072
- import { readdir as readdir10, readFile as readFile13, stat as stat13 } from "node:fs/promises";
12764
+ import { readdir as readdir11, readFile as readFile13, stat as stat14 } from "node:fs/promises";
12073
12765
  import os12 from "node:os";
12074
- import path20 from "node:path";
12766
+ import path21 from "node:path";
12075
12767
  function parseQoderPaths(filePath) {
12076
- const parts = filePath.split(path20.sep);
12768
+ const parts = filePath.split(path21.sep);
12077
12769
  const subagentsIdx = parts.lastIndexOf("subagents");
12078
12770
  let sessionId = "";
12079
12771
  let projectName = "";
@@ -12083,17 +12775,17 @@ function parseQoderPaths(filePath) {
12083
12775
  sessionId = parts[subagentsIdx - 1];
12084
12776
  projectName = parts[subagentsIdx - 2];
12085
12777
  const projectsIdx = parts.lastIndexOf("projects");
12086
- configDir2 = parts.slice(0, projectsIdx).join(path20.sep);
12087
- mainTranscriptPath = [...parts.slice(0, subagentsIdx - 1), `${sessionId}.jsonl`].join(path20.sep);
12778
+ configDir2 = parts.slice(0, projectsIdx).join(path21.sep);
12779
+ mainTranscriptPath = [...parts.slice(0, subagentsIdx - 1), `${sessionId}.jsonl`].join(path21.sep);
12088
12780
  } else {
12089
12781
  const filename = parts.at(-1) || "";
12090
- sessionId = path20.basename(filename, ".jsonl");
12782
+ sessionId = path21.basename(filename, ".jsonl");
12091
12783
  projectName = parts.at(-2) || "";
12092
12784
  if (projectName === "transcript") {
12093
12785
  projectName = parts.at(-3) || "";
12094
12786
  }
12095
12787
  const projectsIdx = parts.lastIndexOf("projects");
12096
- configDir2 = parts.slice(0, projectsIdx).join(path20.sep);
12788
+ configDir2 = parts.slice(0, projectsIdx).join(path21.sep);
12097
12789
  }
12098
12790
  return { configDir: configDir2, projectName, sessionId, mainTranscriptPath };
12099
12791
  }
@@ -12132,10 +12824,24 @@ async function parseModelNamesFromDynamicTexts2(dynamicTextsPath) {
12132
12824
  }
12133
12825
  }
12134
12826
  async function loadQoderModelNames(configDir2, home) {
12135
- const map = await parseModelNamesFromDynamicTexts2(path20.join(configDir2, ".auth", "dynamic-texts.json"));
12827
+ const map = {};
12828
+ for (const appDirName of ["Qoder", "QoderCN"]) {
12829
+ const ideMap = await loadQoderIdeModelCatalog(appDirName, home);
12830
+ for (const [key, val] of Object.entries(ideMap)) {
12831
+ if (!(key in map)) {
12832
+ map[key] = val;
12833
+ }
12834
+ }
12835
+ }
12836
+ const textsMap = await parseModelNamesFromDynamicTexts2(path21.join(configDir2, ".auth", "dynamic-texts.json"));
12837
+ for (const [key, val] of Object.entries(textsMap)) {
12838
+ if (!(key in map)) {
12839
+ map[key] = val;
12840
+ }
12841
+ }
12136
12842
  const siblingConfigDir = configDir2.replace(/\.qoder$/, ".qoder-cn");
12137
12843
  if (siblingConfigDir !== configDir2) {
12138
- const siblingMap = await parseModelNamesFromDynamicTexts2(path20.join(siblingConfigDir, ".auth", "dynamic-texts.json"));
12844
+ const siblingMap = await parseModelNamesFromDynamicTexts2(path21.join(siblingConfigDir, ".auth", "dynamic-texts.json"));
12139
12845
  for (const [key, val] of Object.entries(siblingMap)) {
12140
12846
  if (!(key in map)) {
12141
12847
  map[key] = val;
@@ -12143,11 +12849,11 @@ async function loadQoderModelNames(configDir2, home) {
12143
12849
  }
12144
12850
  }
12145
12851
  if (isQwenworkConfigRoot(configDir2)) {
12146
- for (const dir of [path20.join(home, ".qoder"), path20.join(home, ".qoder-cn")]) {
12147
- if (path20.resolve(dir) === path20.resolve(configDir2)) {
12852
+ for (const dir of [path21.join(home, ".qoder"), path21.join(home, ".qoder-cn")]) {
12853
+ if (path21.resolve(dir) === path21.resolve(configDir2)) {
12148
12854
  continue;
12149
12855
  }
12150
- const fallbackMap = await parseModelNamesFromDynamicTexts2(path20.join(dir, ".auth", "dynamic-texts.json"));
12856
+ const fallbackMap = await parseModelNamesFromDynamicTexts2(path21.join(dir, ".auth", "dynamic-texts.json"));
12151
12857
  for (const [key, val] of Object.entries(fallbackMap)) {
12152
12858
  if (!(key in map)) {
12153
12859
  map[key] = val;
@@ -12155,36 +12861,28 @@ async function loadQoderModelNames(configDir2, home) {
12155
12861
  }
12156
12862
  }
12157
12863
  }
12158
- for (const appDirName of ["Qoder", "QoderCN"]) {
12159
- const ideMap = await loadQoderIdeModelCatalog(appDirName, home);
12160
- for (const [key, val] of Object.entries(ideMap)) {
12161
- if (!(key in map)) {
12162
- map[key] = val;
12163
- }
12164
- }
12165
- }
12166
12864
  return map;
12167
12865
  }
12168
12866
  function isQwenworkConfigRoot(configDir2) {
12169
- const name = path20.basename(path20.resolve(configDir2));
12867
+ const name = path21.basename(path21.resolve(configDir2));
12170
12868
  if (name === ".qwenworkcn" || name === ".qwenwork") {
12171
12869
  return true;
12172
12870
  }
12173
12871
  const override = process.env.QWENWORK_CONFIG_DIR;
12174
- return Boolean(override && override.trim() && path20.basename(path20.resolve(override)) === name);
12872
+ return Boolean(override && override.trim() && path21.basename(path21.resolve(override)) === name);
12175
12873
  }
12176
12874
  var FAILED_SEGMENT_STOP_REASONS = /* @__PURE__ */ new Set(["cancelled", "canceled", "error", "failed", "refusal"]);
12177
12875
  async function loadQoderSegmentModelCalls(filePath, isSubagentSession, modelMap) {
12178
12876
  const { configDir: configDir2, projectName, sessionId } = parseQoderPaths(filePath);
12179
- const segmentsPath = path20.join(configDir2, "logs", "sessions", projectName, sessionId, "segments");
12877
+ const segmentsPath = path21.join(configDir2, "logs", "sessions", projectName, sessionId, "segments");
12180
12878
  const modelCalls = [];
12181
12879
  try {
12182
- const files = await readdir10(segmentsPath);
12880
+ const files = await readdir11(segmentsPath);
12183
12881
  for (const file of files) {
12184
12882
  if (!file.endsWith(".jsonl")) {
12185
12883
  continue;
12186
12884
  }
12187
- const content = await readFile13(path20.join(segmentsPath, file), "utf8");
12885
+ const content = await readFile13(path21.join(segmentsPath, file), "utf8");
12188
12886
  let currentTurnIsSubagent = false;
12189
12887
  for (const line of content.split("\n").filter(Boolean)) {
12190
12888
  const raw = parseJsonLine(line);
@@ -12229,7 +12927,7 @@ async function parseQoderSessionFile(filePath, options) {
12229
12927
  let cwd;
12230
12928
  let project = projectContext.project;
12231
12929
  let model;
12232
- const home = path20.resolve(stringOption(options.home) || os12.homedir());
12930
+ const home = path21.resolve(stringOption(options.home) || os12.homedir());
12233
12931
  const modelMap = await loadQoderModelNames(configDir2, home);
12234
12932
  const qwenworkRoot = isQwenworkConfigRoot(configDir2);
12235
12933
  const isSubagentSession = filePath.includes("subagents");
@@ -12265,7 +12963,7 @@ async function parseQoderSessionFile(filePath, options) {
12265
12963
  sessionId = stringField(raw, "sessionId") || sessionId;
12266
12964
  state.sessionId = sessionId;
12267
12965
  cwd = stringField(raw, "cwd") || cwd;
12268
- project = projectContext.project || (cwd ? path20.basename(cwd) : project || await qoderProjectFromFilePath(filePath, options));
12966
+ project = projectContext.project || (cwd ? path21.basename(cwd) : project || await qoderProjectFromFilePath(filePath, options));
12269
12967
  if (!ts) {
12270
12968
  continue;
12271
12969
  }
@@ -12576,7 +13274,7 @@ async function parseQoderSessionFile(filePath, options) {
12576
13274
  }
12577
13275
  dbModelCalls ??= await loadQoderDbModelCalls("Qoder", parsedPaths.sessionId, modelMap);
12578
13276
  if (dbModelCalls.rootSessionId) {
12579
- const parentPath = path20.join(path20.dirname(filePath), `${dbModelCalls.rootSessionId}.jsonl`);
13277
+ const parentPath = path21.join(path21.dirname(filePath), `${dbModelCalls.rootSessionId}.jsonl`);
12580
13278
  const parentSourcePathHash = `sha256:${createStableHash(parentPath)}`;
12581
13279
  return withoutSubagentTurnEvents(validEvents).map((event) => rebuildEventIdentity4({
12582
13280
  ...event,
@@ -12693,41 +13391,41 @@ function qoderExtractText(value) {
12693
13391
  }
12694
13392
  async function qoderProjectContextFromLines(filePath, lines, options, configDir2) {
12695
13393
  const { projectName: projectDir, sessionId } = parseQoderPaths(filePath);
12696
- const isSubagent = filePath.includes(`${path20.sep}subagents${path20.sep}`);
13394
+ const isSubagent = filePath.includes(`${path21.sep}subagents${path21.sep}`);
12697
13395
  const inherited = isSubagent ? await readPersistedSessionContextFromOptions(options, sessionId) : void 0;
12698
13396
  let cwds = [];
12699
13397
  const workspaceDirs = [];
12700
13398
  for (const line of lines) {
12701
13399
  const raw = parseJsonLine(line);
12702
13400
  const cwd = raw ? stringField(raw, "cwd") : void 0;
12703
- if (cwd && path20.isAbsolute(cwd)) {
13401
+ if (cwd && path21.isAbsolute(cwd)) {
12704
13402
  cwds.push(cwd);
12705
13403
  }
12706
13404
  if (raw && stringField(raw, "type") === "workspace-directories") {
12707
13405
  for (const dir of arrayField5(raw, "directories")) {
12708
- if (typeof dir === "string" && path20.isAbsolute(dir)) {
13406
+ if (typeof dir === "string" && path21.isAbsolute(dir)) {
12709
13407
  workspaceDirs.push(dir);
12710
13408
  }
12711
13409
  }
12712
13410
  }
12713
13411
  }
12714
13412
  if (isSubagent) {
12715
- if (inherited?.cwd && path20.isAbsolute(inherited.cwd)) {
13413
+ if (inherited?.cwd && path21.isAbsolute(inherited.cwd)) {
12716
13414
  cwds = [inherited.cwd];
12717
13415
  } else {
12718
- const parentSessionPath = path20.join(configDir2, "projects", projectDir, `${sessionId}.jsonl`);
13416
+ const parentSessionPath = path21.join(configDir2, "projects", projectDir, `${sessionId}.jsonl`);
12719
13417
  try {
12720
13418
  const parentText = await readFile13(parentSessionPath, "utf8");
12721
13419
  const parentCwds = [];
12722
13420
  for (const line of parentText.split("\n").filter(Boolean)) {
12723
13421
  const raw = parseJsonLine(line);
12724
13422
  const cwd = raw ? stringField(raw, "cwd") : void 0;
12725
- if (cwd && path20.isAbsolute(cwd)) {
13423
+ if (cwd && path21.isAbsolute(cwd)) {
12726
13424
  parentCwds.push(cwd);
12727
13425
  }
12728
13426
  if (workspaceDirs.length === 0 && raw && stringField(raw, "type") === "workspace-directories") {
12729
13427
  for (const dir of arrayField5(raw, "directories")) {
12730
- if (typeof dir === "string" && path20.isAbsolute(dir)) {
13428
+ if (typeof dir === "string" && path21.isAbsolute(dir)) {
12731
13429
  workspaceDirs.push(dir);
12732
13430
  }
12733
13431
  }
@@ -12747,29 +13445,29 @@ async function qoderProjectContextFromLines(filePath, lines, options, configDir2
12747
13445
  }
12748
13446
  }
12749
13447
  const root = await gitRootFromCwds3(cwds) || qoderProjectRootFromCwds(projectDir, cwds);
12750
- const project = inherited?.project || (cwds.length > 0 ? path20.basename(cwds[0]) : root ? path20.basename(root) : await qoderProjectFromFilePath(filePath, options));
13448
+ const project = inherited?.project || (cwds.length > 0 ? path21.basename(cwds[0]) : root ? path21.basename(root) : await qoderProjectFromFilePath(filePath, options));
12751
13449
  return {
12752
13450
  project,
12753
13451
  workspaceId: createWorkspaceId({ projectName: project, repoRoot: root })
12754
13452
  };
12755
13453
  }
12756
13454
  function pathInsideDir(candidate, dir) {
12757
- const resolvedDir = path20.resolve(dir);
12758
- const resolved = path20.resolve(candidate);
12759
- return resolved === resolvedDir || resolved.startsWith(`${resolvedDir}${path20.sep}`);
13455
+ const resolvedDir = path21.resolve(dir);
13456
+ const resolved = path21.resolve(candidate);
13457
+ return resolved === resolvedDir || resolved.startsWith(`${resolvedDir}${path21.sep}`);
12760
13458
  }
12761
13459
  async function gitRootFromCwds3(cwds) {
12762
13460
  const seen = /* @__PURE__ */ new Set();
12763
13461
  for (const cwd of cwds) {
12764
- let current = path20.resolve(cwd);
13462
+ let current = path21.resolve(cwd);
12765
13463
  while (!seen.has(current)) {
12766
13464
  seen.add(current);
12767
13465
  try {
12768
- await stat13(path20.join(current, ".git"));
13466
+ await stat14(path21.join(current, ".git"));
12769
13467
  return current;
12770
13468
  } catch {
12771
13469
  }
12772
- const parent = path20.dirname(current);
13470
+ const parent = path21.dirname(current);
12773
13471
  if (parent === current) {
12774
13472
  break;
12775
13473
  }
@@ -12780,12 +13478,12 @@ async function gitRootFromCwds3(cwds) {
12780
13478
  }
12781
13479
  function qoderProjectRootFromCwds(projectDir, cwds) {
12782
13480
  for (const cwd of cwds) {
12783
- let current = path20.resolve(cwd);
13481
+ let current = path21.resolve(cwd);
12784
13482
  while (true) {
12785
13483
  if (qoderEncodedVariants(current).includes(projectDir)) {
12786
13484
  return current;
12787
13485
  }
12788
- const parent = path20.dirname(current);
13486
+ const parent = path21.dirname(current);
12789
13487
  if (parent === current) {
12790
13488
  break;
12791
13489
  }
@@ -12795,7 +13493,7 @@ function qoderProjectRootFromCwds(projectDir, cwds) {
12795
13493
  return void 0;
12796
13494
  }
12797
13495
  function rawQoderProjectPath(value) {
12798
- return path20.resolve(value).split(path20.sep).join("-");
13496
+ return path21.resolve(value).split(path21.sep).join("-");
12799
13497
  }
12800
13498
  function qoderEncodedVariants(value) {
12801
13499
  const raw = rawQoderProjectPath(value);
@@ -12816,11 +13514,11 @@ function qoderEncodedProjectSuffix(projectDir, home) {
12816
13514
  return void 0;
12817
13515
  }
12818
13516
  async function qoderProjectFromFilePath(filePath, options) {
12819
- const projectDir = path20.basename(path20.dirname(filePath));
12820
- const home = options ? path20.resolve(stringOption(options.home) || os12.homedir()) : os12.homedir();
13517
+ const projectDir = path21.basename(path21.dirname(filePath));
13518
+ const home = options ? path21.resolve(stringOption(options.home) || os12.homedir()) : os12.homedir();
12821
13519
  const resolved = await resolveQoderProjectPath(projectDir, home);
12822
13520
  if (resolved) {
12823
- return path20.basename(resolved);
13521
+ return path21.basename(resolved);
12824
13522
  }
12825
13523
  const suffix = qoderEncodedProjectSuffix(projectDir, home);
12826
13524
  if (suffix) {
@@ -12841,12 +13539,12 @@ async function resolveQoderProjectPath(projectDir, home) {
12841
13539
  while (currentEncodedVariants.some((prefix) => projectDir.startsWith(`${prefix}-`))) {
12842
13540
  let matchedChild;
12843
13541
  try {
12844
- const entries = await readdir10(current, { withFileTypes: true });
13542
+ const entries = await readdir11(current, { withFileTypes: true });
12845
13543
  for (const entry of entries) {
12846
13544
  if (!entry.isDirectory()) {
12847
13545
  continue;
12848
13546
  }
12849
- const candidate = path20.join(current, entry.name);
13547
+ const candidate = path21.join(current, entry.name);
12850
13548
  const candidateVariants = qoderEncodedVariants(candidate);
12851
13549
  if (candidateVariants.includes(projectDir)) {
12852
13550
  return candidate;
@@ -12891,19 +13589,19 @@ function hookConfig7() {
12891
13589
  function qoderConfigDir(home, env) {
12892
13590
  const override = env?.QODER_CONFIG_DIR;
12893
13591
  if (override && override.trim()) {
12894
- return path20.resolve(override);
13592
+ return path21.resolve(override);
12895
13593
  }
12896
- return path20.join(home, ".qoder");
13594
+ return path21.join(home, ".qoder");
12897
13595
  }
12898
13596
  function qwenworkConfigDir(home, env) {
12899
13597
  const override = env?.QWENWORK_CONFIG_DIR;
12900
13598
  if (override && override.trim()) {
12901
- return path20.resolve(override);
13599
+ return path21.resolve(override);
12902
13600
  }
12903
- return path20.join(home, ".qwenworkcn");
13601
+ return path21.join(home, ".qwenworkcn");
12904
13602
  }
12905
13603
  function qoderConfigDirs(home, env) {
12906
- return [...new Set([qoderConfigDir(home, env), qwenworkConfigDir(home, env)].map((dir) => path20.resolve(dir)))];
13604
+ return [...new Set([qoderConfigDir(home, env), qwenworkConfigDir(home, env)].map((dir) => path21.resolve(dir)))];
12907
13605
  }
12908
13606
  function createQoderAdapter() {
12909
13607
  return {
@@ -12915,11 +13613,11 @@ function createQoderAdapter() {
12915
13613
  return qoderConfigDir(home, env);
12916
13614
  },
12917
13615
  installedPath(home, env) {
12918
- return path20.join(qoderConfigDir(home, env), "settings.json");
13616
+ return path21.join(qoderConfigDir(home, env), "settings.json");
12919
13617
  },
12920
13618
  async isInstalled(home, env) {
12921
13619
  return isHooksJsonInstalled(
12922
- path20.join(qoderConfigDir(home, env), "settings.json"),
13620
+ path21.join(qoderConfigDir(home, env), "settings.json"),
12923
13621
  "vibetime hook --agent qoder"
12924
13622
  );
12925
13623
  },
@@ -12928,16 +13626,16 @@ function createQoderAdapter() {
12928
13626
  const targets = [primary, ...variants.filter((dir) => existsSync(dir))];
12929
13627
  return targets.map((base) => ({
12930
13628
  kind: "hooks-json",
12931
- path: path20.join(base, "settings.json"),
13629
+ path: path21.join(base, "settings.json"),
12932
13630
  content: hookConfig7()
12933
13631
  }));
12934
13632
  },
12935
13633
  sourcePaths(home, env) {
12936
- const paths = qoderConfigDirs(home, env).map((base2) => path20.join(base2, "projects"));
13634
+ const paths = qoderConfigDirs(home, env).map((base2) => path21.join(base2, "projects"));
12937
13635
  const base = qoderConfigDir(home, env);
12938
13636
  paths.push(
12939
- path20.join(base, ".qoder.json"),
12940
- path20.join(home, ".qoder.json")
13637
+ path21.join(base, ".qoder.json"),
13638
+ path21.join(home, ".qoder.json")
12941
13639
  );
12942
13640
  return paths;
12943
13641
  },
@@ -12973,35 +13671,35 @@ function normalizeId(id) {
12973
13671
  }
12974
13672
 
12975
13673
  // src/adapters/workbuddy.ts
12976
- import { readdir as readdir11, readFile as readFile14, stat as stat14 } from "node:fs/promises";
12977
- import path21 from "node:path";
13674
+ import { readdir as readdir12, readFile as readFile14, stat as stat15 } from "node:fs/promises";
13675
+ import path22 from "node:path";
12978
13676
  function workbuddyProjectsDir(home, env) {
12979
13677
  const override = env?.WORKBUDDY_PROJECTS_DIR || env?.WORKBUDDY_HOME;
12980
13678
  if (override && override.trim()) {
12981
- return path21.resolve(override, override.endsWith("projects") ? "" : "projects");
13679
+ return path22.resolve(override, override.endsWith("projects") ? "" : "projects");
12982
13680
  }
12983
- return path21.join(home, ".workbuddy", "projects");
13681
+ return path22.join(home, ".workbuddy", "projects");
12984
13682
  }
12985
13683
  function workbuddyBaseDir(home, env) {
12986
13684
  const override = env?.WORKBUDDY_HOME;
12987
13685
  if (override && override.trim()) {
12988
- return path21.resolve(override);
13686
+ return path22.resolve(override);
12989
13687
  }
12990
- return path21.join(home, ".workbuddy");
13688
+ return path22.join(home, ".workbuddy");
12991
13689
  }
12992
- function projectFromCwd(cwd, fallback) {
13690
+ function projectFromCwd2(cwd, fallback) {
12993
13691
  if (!cwd) {
12994
13692
  return fallback;
12995
13693
  }
12996
- return path21.basename(cwd) || fallback;
13694
+ return path22.basename(cwd) || fallback;
12997
13695
  }
12998
- function sourceHash(filePath) {
13696
+ function sourceHash2(filePath) {
12999
13697
  return `sha256:${createStableHash(filePath)}`;
13000
13698
  }
13001
- function makeEvent(event, line, filePath, options) {
13699
+ function makeEvent2(event, line, filePath, options) {
13002
13700
  const withRefs = withBackfillRefs(event, {
13003
13701
  filePath,
13004
- sourcePathHash: sourceHash(filePath),
13702
+ sourcePathHash: sourceHash2(filePath),
13005
13703
  lineNumber: line.lineNumber,
13006
13704
  topType: stringField(line.record, "type"),
13007
13705
  payloadType: stringField(line.record, "role") || stringField(line.record, "name"),
@@ -13081,7 +13779,7 @@ function isHiddenUserMessage(record) {
13081
13779
  return providerData.skipRun === true || providerData.isMeta === true || providerData.isCompactInternal === true || providerData.isCompact === true || providerData.isTeammateMessage === true || (stringField(providerData, "agentPurpose") || "").toLowerCase().includes("compact");
13082
13780
  }
13083
13781
  function workbuddySubagentRefs(lines) {
13084
- const refs2 = {};
13782
+ const refs3 = {};
13085
13783
  const keys = [
13086
13784
  ["parentSessionId", ["parent_session_id", "parentSessionId"]],
13087
13785
  ["parentToolCallId", ["parent_tool_call_id", "parentToolCallId"]],
@@ -13091,19 +13789,19 @@ function workbuddySubagentRefs(lines) {
13091
13789
  for (const line of lines) {
13092
13790
  const providerData = objectField(line.record, "providerData");
13093
13791
  for (const [ref, aliases] of keys) {
13094
- if (refs2[ref]) {
13792
+ if (refs3[ref]) {
13095
13793
  continue;
13096
13794
  }
13097
13795
  for (const alias of aliases) {
13098
13796
  const value = stringField(line.record, alias) || stringField(providerData, alias);
13099
13797
  if (value) {
13100
- refs2[ref] = value;
13798
+ refs3[ref] = value;
13101
13799
  break;
13102
13800
  }
13103
13801
  }
13104
13802
  }
13105
13803
  }
13106
- return refs2;
13804
+ return refs3;
13107
13805
  }
13108
13806
  function toolCallFailed(record) {
13109
13807
  const providerData = objectField(record, "providerData");
@@ -13131,10 +13829,10 @@ async function parseWorkbuddySessionFile(filePath, options) {
13131
13829
  }
13132
13830
  const events = [];
13133
13831
  const first = lines[0].record;
13134
- const sessionId = stringField(first, "sessionId") || path21.basename(filePath, ".jsonl");
13135
- const fallbackProject = path21.basename(path21.dirname(filePath));
13832
+ const sessionId = stringField(first, "sessionId") || path22.basename(filePath, ".jsonl");
13833
+ const fallbackProject = path22.basename(path22.dirname(filePath));
13136
13834
  const cwd = lines.map((line) => stringField(line.record, "cwd")).find(Boolean);
13137
- const project = projectFromCwd(cwd, fallbackProject);
13835
+ const project = projectFromCwd2(cwd, fallbackProject);
13138
13836
  const workspaceId = createWorkspaceId({ projectName: project, repoRoot: cwd });
13139
13837
  const sessionPrefix = `workbuddy:${sessionId}`;
13140
13838
  const toolStarts = /* @__PURE__ */ new Map();
@@ -13149,7 +13847,7 @@ async function parseWorkbuddySessionFile(filePath, options) {
13149
13847
  return void 0;
13150
13848
  }
13151
13849
  const failed = turnLastAssistantStatus !== void 0 && ["incomplete", "failed", "cancelled"].includes(turnLastAssistantStatus);
13152
- return makeEvent({
13850
+ return makeEvent2({
13153
13851
  schemaVersion: AGENT_TIME_SCHEMA_VERSION,
13154
13852
  ts: turnLastTs,
13155
13853
  type: failed ? "turn.failed" : "turn.completed",
@@ -13166,7 +13864,7 @@ async function parseWorkbuddySessionFile(filePath, options) {
13166
13864
  };
13167
13865
  const firstTs = lines.map((line) => timestampFrom(numberField(line.record, "timestamp"))).find(Boolean);
13168
13866
  if (firstTs) {
13169
- const event = makeEvent({
13867
+ const event = makeEvent2({
13170
13868
  schemaVersion: AGENT_TIME_SCHEMA_VERSION,
13171
13869
  ts: firstTs,
13172
13870
  type: "session.started",
@@ -13206,7 +13904,7 @@ async function parseWorkbuddySessionFile(filePath, options) {
13206
13904
  turnLastAssistantStatus = void 0;
13207
13905
  const promptChars = contentLength(record.content);
13208
13906
  for (const event of [
13209
- makeEvent({
13907
+ makeEvent2({
13210
13908
  schemaVersion: AGENT_TIME_SCHEMA_VERSION,
13211
13909
  ts,
13212
13910
  type: "turn.started",
@@ -13220,7 +13918,7 @@ async function parseWorkbuddySessionFile(filePath, options) {
13220
13918
  confidence: "derived",
13221
13919
  refs: { sourceId: `${sourceId}:turn` }
13222
13920
  }, line, filePath, options),
13223
- makeEvent({
13921
+ makeEvent2({
13224
13922
  schemaVersion: AGENT_TIME_SCHEMA_VERSION,
13225
13923
  ts,
13226
13924
  type: "prompt.submitted",
@@ -13249,7 +13947,7 @@ async function parseWorkbuddySessionFile(filePath, options) {
13249
13947
  const metrics = workbuddyUsageMetrics(record);
13250
13948
  if (metrics) {
13251
13949
  const model = stringField(objectField(record, "providerData"), "model");
13252
- const usage = makeEvent({
13950
+ const usage = makeEvent2({
13253
13951
  schemaVersion: AGENT_TIME_SCHEMA_VERSION,
13254
13952
  ts,
13255
13953
  type: "model.usage",
@@ -13278,7 +13976,7 @@ async function parseWorkbuddySessionFile(filePath, options) {
13278
13976
  const callId = stringField(record, "callId");
13279
13977
  if (tool && callId) {
13280
13978
  toolStarts.set(`${sessionId}:${callId}`, { line, ts, tool, callId });
13281
- const started = makeEvent({
13979
+ const started = makeEvent2({
13282
13980
  schemaVersion: AGENT_TIME_SCHEMA_VERSION,
13283
13981
  ts,
13284
13982
  type: "tool.started",
@@ -13306,7 +14004,7 @@ async function parseWorkbuddySessionFile(filePath, options) {
13306
14004
  if (isPlainObject(toolInput)) {
13307
14005
  const fileActivities = claudeStyleToolFileActivities(tool, toolInput, ts, cwd);
13308
14006
  if (fileActivities.length > 0) {
13309
- const fileEvent = makeEvent({
14007
+ const fileEvent = makeEvent2({
13310
14008
  schemaVersion: AGENT_TIME_SCHEMA_VERSION,
13311
14009
  ts,
13312
14010
  type: eventTypeFromFileActivities(fileActivities),
@@ -13332,7 +14030,7 @@ async function parseWorkbuddySessionFile(filePath, options) {
13332
14030
  const metrics = workbuddyUsageMetrics(record);
13333
14031
  const model = stringField(objectField(record, "providerData"), "model");
13334
14032
  if (metrics || model) {
13335
- const usage = makeEvent({
14033
+ const usage = makeEvent2({
13336
14034
  schemaVersion: AGENT_TIME_SCHEMA_VERSION,
13337
14035
  ts,
13338
14036
  type: "model.usage",
@@ -13361,7 +14059,7 @@ async function parseWorkbuddySessionFile(filePath, options) {
13361
14059
  const start = toolStarts.get(`${sessionId}:${callId}`);
13362
14060
  const durationMs = start?.ts ? Math.max(0, Date.parse(ts) - Date.parse(start.ts)) : void 0;
13363
14061
  const failed = toolCallFailed(record);
13364
- const completed = makeEvent({
14062
+ const completed = makeEvent2({
13365
14063
  schemaVersion: AGENT_TIME_SCHEMA_VERSION,
13366
14064
  ts,
13367
14065
  type: failed ? "tool.failed" : "tool.completed",
@@ -13393,7 +14091,7 @@ async function parseWorkbuddySessionFile(filePath, options) {
13393
14091
  }
13394
14092
  const lastTs = lastLine ? timestampFrom(numberField(lastLine.record, "timestamp")) : void 0;
13395
14093
  if (lastLine && lastTs) {
13396
- const event = makeEvent({
14094
+ const event = makeEvent2({
13397
14095
  schemaVersion: AGENT_TIME_SCHEMA_VERSION,
13398
14096
  ts: lastTs,
13399
14097
  type: "session.ended",
@@ -13416,17 +14114,17 @@ async function workbuddyBackfillFiles(sourceRoot, home, env) {
13416
14114
  const base = sourceRoot || workbuddyProjectsDir(home, env);
13417
14115
  const files = [];
13418
14116
  try {
13419
- const projects = await readdir11(base, { withFileTypes: true });
14117
+ const projects = await readdir12(base, { withFileTypes: true });
13420
14118
  for (const project of projects) {
13421
14119
  if (!project.isDirectory()) {
13422
14120
  continue;
13423
14121
  }
13424
- const projectDir = path21.join(base, project.name);
13425
- const entries = await readdir11(projectDir, { withFileTypes: true });
14122
+ const projectDir = path22.join(base, project.name);
14123
+ const entries = await readdir12(projectDir, { withFileTypes: true });
13426
14124
  for (const entry of entries) {
13427
14125
  if (entry.isFile() && entry.name.endsWith(".jsonl")) {
13428
- const filePath = path21.join(projectDir, entry.name);
13429
- const info = await stat14(filePath);
14126
+ const filePath = path22.join(projectDir, entry.name);
14127
+ const info = await stat15(filePath);
13430
14128
  files.push({ path: filePath, modifiedAt: info.mtime.toISOString() });
13431
14129
  }
13432
14130
  }
@@ -13463,18 +14161,18 @@ function createWorkbuddyAdapter() {
13463
14161
  return workbuddyProjectsDir(home, env);
13464
14162
  },
13465
14163
  installedPath(home, env) {
13466
- return path21.join(workbuddyBaseDir(home, env), "settings.json");
14164
+ return path22.join(workbuddyBaseDir(home, env), "settings.json");
13467
14165
  },
13468
14166
  async isInstalled(home, env) {
13469
14167
  return isHooksJsonInstalled(
13470
- path21.join(workbuddyBaseDir(home, env), "settings.json"),
14168
+ path22.join(workbuddyBaseDir(home, env), "settings.json"),
13471
14169
  "vibetime hook --agent workbuddy"
13472
14170
  );
13473
14171
  },
13474
14172
  installEntries(home, env) {
13475
14173
  return [{
13476
14174
  kind: "hooks-json",
13477
- path: path21.join(workbuddyBaseDir(home, env), "settings.json"),
14175
+ path: path22.join(workbuddyBaseDir(home, env), "settings.json"),
13478
14176
  content: hookConfig8()
13479
14177
  }];
13480
14178
  },
@@ -13487,22 +14185,22 @@ function createWorkbuddyAdapter() {
13487
14185
 
13488
14186
  // src/adapters/zcode.ts
13489
14187
  import { execFile } from "node:child_process";
13490
- import { readFile as readFile15, stat as stat15 } from "node:fs/promises";
13491
- import path22 from "node:path";
14188
+ import { readFile as readFile15, stat as stat16 } from "node:fs/promises";
14189
+ import path23 from "node:path";
13492
14190
  import { promisify as promisify2 } from "node:util";
13493
14191
  var execFileAsync = promisify2(execFile);
13494
14192
  function zcodeCliDir(home, env) {
13495
14193
  const override = env?.ZCODE_CLI_DIR || env?.ZCODE_HOME;
13496
14194
  if (override && override.trim()) {
13497
- return path22.resolve(override, override.endsWith("cli") ? "" : "cli");
14195
+ return path23.resolve(override, override.endsWith("cli") ? "" : "cli");
13498
14196
  }
13499
- return path22.join(home, ".zcode", "cli");
14197
+ return path23.join(home, ".zcode", "cli");
13500
14198
  }
13501
14199
  function zcodeDbPath(home, env) {
13502
- return path22.join(zcodeCliDir(home, env), "db", "db.sqlite");
14200
+ return path23.join(zcodeCliDir(home, env), "db", "db.sqlite");
13503
14201
  }
13504
14202
  function zcodeConfigPath(home, env) {
13505
- return path22.join(zcodeCliDir(home, env), "config.json");
14203
+ return path23.join(zcodeCliDir(home, env), "config.json");
13506
14204
  }
13507
14205
  var zcodeHandler = (msg) => hookHandler("zcode", msg);
13508
14206
  function hookConfig9() {
@@ -13526,7 +14224,7 @@ var providerNameCache = null;
13526
14224
  async function loadProviderNames(configPath2) {
13527
14225
  let fileMtime = 0;
13528
14226
  try {
13529
- const info = await stat15(configPath2);
14227
+ const info = await stat16(configPath2);
13530
14228
  fileMtime = info.mtimeMs;
13531
14229
  } catch {
13532
14230
  return /* @__PURE__ */ new Map();
@@ -13550,19 +14248,19 @@ async function loadProviderNames(configPath2) {
13550
14248
  providerNameCache = { path: configPath2, mtimeMs: fileMtime, map };
13551
14249
  return map;
13552
14250
  }
13553
- function sourceHash2(filePath) {
14251
+ function sourceHash3(filePath) {
13554
14252
  return `sha256:${createStableHash(filePath)}`;
13555
14253
  }
13556
14254
  function projectFromDirectory(directory) {
13557
- return directory ? path22.basename(directory) || "zcode" : "zcode";
14255
+ return directory ? path23.basename(directory) || "zcode" : "zcode";
13558
14256
  }
13559
14257
  function isoFromMs(value) {
13560
14258
  return timestampFrom(typeof value === "number" ? value : Number(value));
13561
14259
  }
13562
- function makeEvent2(event, row, rowNumber, filePath, options) {
14260
+ function makeEvent3(event, row, rowNumber, filePath, options) {
13563
14261
  const withRefs = withBackfillRefs(event, {
13564
14262
  filePath,
13565
- sourcePathHash: sourceHash2(filePath),
14263
+ sourcePathHash: sourceHash3(filePath),
13566
14264
  lineNumber: rowNumber,
13567
14265
  topType: row.kind,
13568
14266
  payloadType: stringField(row, "status") || stringField(row, "query_source") || stringField(row, "tool_name"),
@@ -13570,7 +14268,7 @@ function makeEvent2(event, row, rowNumber, filePath, options) {
13570
14268
  });
13571
14269
  return validateCanonicalEvent(withRefs).valid ? withRefs : void 0;
13572
14270
  }
13573
- function refs(values) {
14271
+ function refs2(values) {
13574
14272
  const out = {};
13575
14273
  for (const [key, value] of Object.entries(values)) {
13576
14274
  if (value !== void 0 && value !== "") {
@@ -13727,7 +14425,7 @@ function resolveRootSessionId2(sessionId, sessions) {
13727
14425
  }
13728
14426
  return current;
13729
14427
  }
13730
- function sessionContext(row, sessions) {
14428
+ function sessionContext2(row, sessions) {
13731
14429
  const sessionId = stringField(row, "session_id") || stringField(row, "id") || "unknown";
13732
14430
  const session = sessions.get(sessionId);
13733
14431
  const cwd = stringField(session, "directory");
@@ -13749,16 +14447,16 @@ async function parseZCodeDb(filePath, options) {
13749
14447
  if (rows.length === 0) {
13750
14448
  return [];
13751
14449
  }
13752
- let candidate = path22.resolve(filePath);
14450
+ let candidate = path23.resolve(filePath);
13753
14451
  let configPath2 = "";
13754
14452
  for (let i = 0; i < 12; i++) {
13755
- const probe = path22.join(candidate, ".zcode", "v2", "config.json");
14453
+ const probe = path23.join(candidate, ".zcode", "v2", "config.json");
13756
14454
  try {
13757
- await stat15(probe);
14455
+ await stat16(probe);
13758
14456
  configPath2 = probe;
13759
14457
  break;
13760
14458
  } catch {
13761
- const parent = path22.dirname(candidate);
14459
+ const parent = path23.dirname(candidate);
13762
14460
  if (parent === candidate) break;
13763
14461
  candidate = parent;
13764
14462
  }
@@ -13782,8 +14480,8 @@ async function parseZCodeDb(filePath, options) {
13782
14480
  if (!id || !ts) {
13783
14481
  return;
13784
14482
  }
13785
- const ctx = sessionContext(row, sessions);
13786
- const event = makeEvent2({
14483
+ const ctx = sessionContext2(row, sessions);
14484
+ const event = makeEvent3({
13787
14485
  schemaVersion: AGENT_TIME_SCHEMA_VERSION,
13788
14486
  ts,
13789
14487
  type: "session.started",
@@ -13795,7 +14493,7 @@ async function parseZCodeDb(filePath, options) {
13795
14493
  parentAgentInstanceId: ctx.parentSessionId,
13796
14494
  agent: "zcode",
13797
14495
  confidence: "exact",
13798
- refs: refs({
14496
+ refs: refs2({
13799
14497
  sourceId: `${id}:session`,
13800
14498
  zcodeTaskType: stringField(row, "task_type"),
13801
14499
  zcodeTitleHash: stringField(row, "title") ? `sha256:${createStableHash(stringField(row, "title"))}` : void 0
@@ -13807,7 +14505,7 @@ async function parseZCodeDb(filePath, options) {
13807
14505
  const linesAdded = numberField(row, "summary_additions");
13808
14506
  const linesRemoved = numberField(row, "summary_deletions");
13809
14507
  const filesChanged = numberField(row, "summary_files");
13810
- const completed = makeEvent2({
14508
+ const completed = makeEvent3({
13811
14509
  schemaVersion: AGENT_TIME_SCHEMA_VERSION,
13812
14510
  ts: completedTs,
13813
14511
  type: "session.ended",
@@ -13832,12 +14530,12 @@ async function parseZCodeDb(filePath, options) {
13832
14530
  if (!rawTurnId || !ts) {
13833
14531
  return;
13834
14532
  }
13835
- const ctx = sessionContext(row, sessions);
14533
+ const ctx = sessionContext2(row, sessions);
13836
14534
  if (ctx.isSubagent) {
13837
14535
  return;
13838
14536
  }
13839
14537
  const turnId = `zcode:${rawTurnId}`;
13840
- const started = makeEvent2({
14538
+ const started = makeEvent3({
13841
14539
  schemaVersion: AGENT_TIME_SCHEMA_VERSION,
13842
14540
  ts,
13843
14541
  type: "turn.started",
@@ -13855,7 +14553,7 @@ async function parseZCodeDb(filePath, options) {
13855
14553
  const completedTs = isoFromMs(numberField(row, "completed_at"));
13856
14554
  if (completedTs) {
13857
14555
  const status = stringField(row, "status");
13858
- const completed = makeEvent2({
14556
+ const completed = makeEvent3({
13859
14557
  schemaVersion: AGENT_TIME_SCHEMA_VERSION,
13860
14558
  ts: completedTs,
13861
14559
  type: "turn.completed",
@@ -13874,7 +14572,7 @@ async function parseZCodeDb(filePath, options) {
13874
14572
  toolCalls: numberField(row, "tool_call_count")
13875
14573
  },
13876
14574
  confidence: "exact",
13877
- refs: refs({ sourceId: `${rawTurnId}:completed`, zcodeStatus: status })
14575
+ refs: refs2({ sourceId: `${rawTurnId}:completed`, zcodeStatus: status })
13878
14576
  }, row, rowNumber, filePath, options);
13879
14577
  if (completed) events.push(completed);
13880
14578
  }
@@ -13885,9 +14583,9 @@ async function parseZCodeDb(filePath, options) {
13885
14583
  if (!ts) {
13886
14584
  return;
13887
14585
  }
13888
- const ctx = sessionContext(row, sessions);
14586
+ const ctx = sessionContext2(row, sessions);
13889
14587
  const modelId = stringField(row, "model_id");
13890
- const usage = makeEvent2({
14588
+ const usage = makeEvent3({
13891
14589
  schemaVersion: AGENT_TIME_SCHEMA_VERSION,
13892
14590
  ts,
13893
14591
  type: "model.usage",
@@ -13904,7 +14602,7 @@ async function parseZCodeDb(filePath, options) {
13904
14602
  success: stringField(row, "status") === "completed",
13905
14603
  metrics: modelMetrics(row),
13906
14604
  confidence: "exact",
13907
- refs: refs({
14605
+ refs: refs2({
13908
14606
  sourceId: stringField(row, "id") || `${ctx.rawSessionId}:model:${rowNumber}`,
13909
14607
  zcodeQuerySource: stringField(row, "query_source"),
13910
14608
  zcodeMode: stringField(row, "mode"),
@@ -13925,10 +14623,10 @@ async function parseZCodeDb(filePath, options) {
13925
14623
  if (!startedTs) {
13926
14624
  return;
13927
14625
  }
13928
- const ctx = sessionContext(row, sessions);
14626
+ const ctx = sessionContext2(row, sessions);
13929
14627
  const turnId = !ctx.isSubagent && stringField(row, "turn_id") ? `zcode:${stringField(row, "turn_id")}` : void 0;
13930
14628
  const spanId = `${ctx.sessionId}:tool:${toolCallId}`;
13931
- const started = makeEvent2({
14629
+ const started = makeEvent3({
13932
14630
  schemaVersion: AGENT_TIME_SCHEMA_VERSION,
13933
14631
  ts: startedTs,
13934
14632
  type: "tool.started",
@@ -13942,7 +14640,7 @@ async function parseZCodeDb(filePath, options) {
13942
14640
  agent: "zcode",
13943
14641
  tool,
13944
14642
  confidence: "exact",
13945
- refs: refs({
14643
+ refs: refs2({
13946
14644
  sourceId: `${toolCallId}:start`,
13947
14645
  zcodeSideEffectScope: stringField(row, "side_effect_scope"),
13948
14646
  zcodeApprovalStatus: stringField(row, "approval_status")
@@ -13951,7 +14649,7 @@ async function parseZCodeDb(filePath, options) {
13951
14649
  if (started) events.push(started);
13952
14650
  if (completedTs) {
13953
14651
  const status = stringField(row, "status");
13954
- const completed = makeEvent2({
14652
+ const completed = makeEvent3({
13955
14653
  schemaVersion: AGENT_TIME_SCHEMA_VERSION,
13956
14654
  ts: completedTs,
13957
14655
  type: status === "completed" ? "tool.completed" : "tool.failed",
@@ -13971,7 +14669,7 @@ async function parseZCodeDb(filePath, options) {
13971
14669
  bytesRead: numberField(row, "output_bytes")
13972
14670
  },
13973
14671
  confidence: "exact",
13974
- refs: refs({
14672
+ refs: refs2({
13975
14673
  sourceId: `${toolCallId}:completed`,
13976
14674
  zcodeStatus: status,
13977
14675
  zcodeExitCode: numberField(row, "exit_code"),
@@ -13986,13 +14684,13 @@ async function parseZCodeDb(filePath, options) {
13986
14684
  }
13987
14685
  async function zcodeBackfillFiles(sourceRoot, home, env) {
13988
14686
  const candidate = sourceRoot || zcodeDbPath(home, env);
13989
- const filePath = candidate.endsWith(".sqlite") ? candidate : path22.join(candidate, "db", "db.sqlite");
14687
+ const filePath = candidate.endsWith(".sqlite") ? candidate : path23.join(candidate, "db", "db.sqlite");
13990
14688
  try {
13991
- const info = await stat15(filePath);
14689
+ const info = await stat16(filePath);
13992
14690
  let modifiedMs = info.mtimeMs;
13993
14691
  for (const suffix of ["-wal", "-shm"]) {
13994
14692
  try {
13995
- const sidecar = await stat15(`${filePath}${suffix}`);
14693
+ const sidecar = await stat16(`${filePath}${suffix}`);
13996
14694
  modifiedMs = Math.max(modifiedMs, sidecar.mtimeMs);
13997
14695
  } catch {
13998
14696
  }
@@ -14036,49 +14734,49 @@ function createZCodeAdapter() {
14036
14734
 
14037
14735
  // src/adapters/zed.ts
14038
14736
  import os13 from "node:os";
14039
- import path23 from "node:path";
14737
+ import path24 from "node:path";
14040
14738
  function zedThreadsCandidates(home, env) {
14041
14739
  const candidates = [];
14042
14740
  const platform2 = process.platform;
14043
14741
  if (platform2 === "darwin") {
14044
- candidates.push(path23.join(home, "Library", "Application Support", "Zed", "threads", "threads.db"));
14742
+ candidates.push(path24.join(home, "Library", "Application Support", "Zed", "threads", "threads.db"));
14045
14743
  } else if (platform2 === "win32") {
14046
14744
  const appdata = env?.APPDATA;
14047
14745
  if (appdata && appdata.trim()) {
14048
- candidates.push(path23.join(path23.resolve(appdata), "Zed", "threads", "threads.db"));
14746
+ candidates.push(path24.join(path24.resolve(appdata), "Zed", "threads", "threads.db"));
14049
14747
  }
14050
- candidates.push(path23.join(home, "AppData", "Roaming", "Zed", "threads", "threads.db"));
14748
+ candidates.push(path24.join(home, "AppData", "Roaming", "Zed", "threads", "threads.db"));
14051
14749
  } else {
14052
14750
  const xdgData = env?.XDG_DATA_HOME;
14053
14751
  if (xdgData && xdgData.trim()) {
14054
- candidates.push(path23.join(path23.resolve(xdgData), "zed", "threads", "threads.db"));
14752
+ candidates.push(path24.join(path24.resolve(xdgData), "zed", "threads", "threads.db"));
14055
14753
  }
14056
- candidates.push(path23.join(home, ".local", "share", "zed", "threads", "threads.db"));
14754
+ candidates.push(path24.join(home, ".local", "share", "zed", "threads", "threads.db"));
14057
14755
  const xdgConfig = env?.XDG_CONFIG_HOME;
14058
14756
  if (xdgConfig && xdgConfig.trim()) {
14059
- candidates.push(path23.join(path23.resolve(xdgConfig), "zed", "threads", "threads.db"));
14757
+ candidates.push(path24.join(path24.resolve(xdgConfig), "zed", "threads", "threads.db"));
14060
14758
  }
14061
- candidates.push(path23.join(home, ".config", "zed", "threads", "threads.db"));
14759
+ candidates.push(path24.join(home, ".config", "zed", "threads", "threads.db"));
14062
14760
  }
14063
14761
  return candidates;
14064
14762
  }
14065
14763
  function zedConfigDir(home, env) {
14066
14764
  const platform2 = process.platform;
14067
14765
  if (platform2 === "darwin") {
14068
- return path23.join(home, "Library", "Application Support", "Zed");
14766
+ return path24.join(home, "Library", "Application Support", "Zed");
14069
14767
  }
14070
14768
  if (platform2 === "win32") {
14071
14769
  const appdata = env?.APPDATA;
14072
14770
  if (appdata && appdata.trim()) {
14073
- return path23.join(path23.resolve(appdata), "Zed");
14771
+ return path24.join(path24.resolve(appdata), "Zed");
14074
14772
  }
14075
- return path23.join(home, "AppData", "Roaming", "Zed");
14773
+ return path24.join(home, "AppData", "Roaming", "Zed");
14076
14774
  }
14077
14775
  const xdgConfig = env?.XDG_CONFIG_HOME;
14078
14776
  if (xdgConfig && xdgConfig.trim()) {
14079
- return path23.join(path23.resolve(xdgConfig), "zed");
14777
+ return path24.join(path24.resolve(xdgConfig), "zed");
14080
14778
  }
14081
- return path23.join(home, ".config", "zed");
14779
+ return path24.join(home, ".config", "zed");
14082
14780
  }
14083
14781
  function baseZedEvent(event) {
14084
14782
  return {
@@ -14142,7 +14840,7 @@ async function parseZedSessionFile(dbPath, options) {
14142
14840
  const folderRaw = row.folder_paths || "";
14143
14841
  const folder = folderRaw.split(/[\n,]/).map((s) => s.trim()).find(Boolean);
14144
14842
  const cwd = folder || void 0;
14145
- const project = cwd ? path23.basename(cwd) : row.summary ? row.summary.slice(0, 40) : void 0;
14843
+ const project = cwd ? path24.basename(cwd) : row.summary ? row.summary.slice(0, 40) : void 0;
14146
14844
  let json;
14147
14845
  try {
14148
14846
  const bytes = row.data_type === "zstd" ? decompress2(new Uint8Array(row.data)) : new Uint8Array(row.data);
@@ -14388,19 +15086,19 @@ async function parseZedSessionFile(dbPath, options) {
14388
15086
  return events.filter((event) => matchesBackfillFilters(event, options));
14389
15087
  }
14390
15088
  async function zedBackfillFiles(sourceRoot, home = os13.homedir(), env) {
14391
- const { stat: stat18 } = await import("node:fs/promises");
15089
+ const { stat: stat19 } = await import("node:fs/promises");
14392
15090
  if (sourceRoot) {
14393
15091
  if (!sourceRoot.endsWith(".db")) {
14394
15092
  return [];
14395
15093
  }
14396
- const info = await stat18(sourceRoot).catch(() => null);
15094
+ const info = await stat19(sourceRoot).catch(() => null);
14397
15095
  if (!info) {
14398
15096
  return [];
14399
15097
  }
14400
15098
  return [{ path: sourceRoot, modifiedAt: info.mtime.toISOString() }];
14401
15099
  }
14402
15100
  for (const candidatePath of zedThreadsCandidates(home, env)) {
14403
- const info = await stat18(candidatePath).catch(() => null);
15101
+ const info = await stat19(candidatePath).catch(() => null);
14404
15102
  if (info) {
14405
15103
  return [{ path: candidatePath, modifiedAt: info.mtime.toISOString() }];
14406
15104
  }
@@ -14417,7 +15115,7 @@ function createZedAdapter() {
14417
15115
  return zedConfigDir(home, env);
14418
15116
  },
14419
15117
  installedPath(home, env) {
14420
- return path23.join(zedConfigDir(home, env), "vibetime-marker");
15118
+ return path24.join(zedConfigDir(home, env), "vibetime-marker");
14421
15119
  },
14422
15120
  async isInstalled() {
14423
15121
  return false;
@@ -15232,19 +15930,19 @@ async function uninstallGeneratedFile(filePath, { dryRun, onWrite }) {
15232
15930
  import { randomUUID } from "node:crypto";
15233
15931
  import { existsSync as existsSync2, mkdirSync, readFileSync as readFileSync2, rmSync, writeFileSync } from "node:fs";
15234
15932
  import { homedir, hostname } from "node:os";
15235
- import path24 from "node:path";
15933
+ import path25 from "node:path";
15236
15934
  function disabledBackfillSourceSet(config) {
15237
15935
  const list = Array.isArray(config.disabledSources) ? config.disabledSources : [];
15238
15936
  return new Set(list.map((id) => String(id).trim()).filter(Boolean));
15239
15937
  }
15240
15938
  function configDir(home = homedir()) {
15241
- return path24.join(home, ".vibetime");
15939
+ return path25.join(home, ".vibetime");
15242
15940
  }
15243
15941
  function configPath(home = homedir()) {
15244
- return path24.join(configDir(home), "config.json");
15942
+ return path25.join(configDir(home), "config.json");
15245
15943
  }
15246
15944
  function machineIdPath(home = homedir()) {
15247
- return path24.join(configDir(home), "machine-id");
15945
+ return path25.join(configDir(home), "machine-id");
15248
15946
  }
15249
15947
  function readConfig(home = homedir()) {
15250
15948
  const file = configPath(home);
@@ -15291,15 +15989,15 @@ function defaultMachineName() {
15291
15989
  init_fs();
15292
15990
 
15293
15991
  // src/lib/logger.ts
15294
- import { appendFile, mkdir as mkdir5, rename as rename2, stat as stat16 } from "node:fs/promises";
15992
+ import { appendFile, mkdir as mkdir5, rename as rename2, stat as stat17 } from "node:fs/promises";
15295
15993
  import { homedir as homedir2 } from "node:os";
15296
- import path25 from "node:path";
15994
+ import path26 from "node:path";
15297
15995
  var MAX_BYTES = 1 * 1024 * 1024;
15298
15996
  function logDir(home = homedir2()) {
15299
- return path25.join(home, ".vibetime", "logs");
15997
+ return path26.join(home, ".vibetime", "logs");
15300
15998
  }
15301
15999
  function logPath(home = homedir2(), name = "cli.log") {
15302
- return path25.join(logDir(home), name);
16000
+ return path26.join(logDir(home), name);
15303
16001
  }
15304
16002
  function serializeError(error) {
15305
16003
  if (error instanceof Error) {
@@ -15309,7 +16007,7 @@ function serializeError(error) {
15309
16007
  }
15310
16008
  async function rotateIfNeeded(file) {
15311
16009
  try {
15312
- const info = await stat16(file);
16010
+ const info = await stat17(file);
15313
16011
  if (info.size > MAX_BYTES) {
15314
16012
  await rename2(file, `${file}.1`).catch(() => {
15315
16013
  });
@@ -15474,8 +16172,8 @@ function buildHeaders(token, machine) {
15474
16172
  ...machine?.platform ? { "x-machine-platform": machine.platform } : {}
15475
16173
  };
15476
16174
  }
15477
- function joinUrl(base, path27) {
15478
- return new URL(path27, base.endsWith("/") ? base : `${base}/`).toString();
16175
+ function joinUrl(base, path28) {
16176
+ return new URL(path28, base.endsWith("/") ? base : `${base}/`).toString();
15479
16177
  }
15480
16178
  async function postRollupBatch(remote, rollups, options = {}) {
15481
16179
  const response = await remote.fetchImpl(joinUrl(remote.baseUrl, "/v3/agent/ingest"), {
@@ -15567,6 +16265,7 @@ function createRegistry() {
15567
16265
  registry.register(createKimiCodeAdapter());
15568
16266
  registry.register(createCursorAdapter());
15569
16267
  registry.register(createGrokBotAdapter());
16268
+ registry.register(createHermesAdapter());
15570
16269
  return registry;
15571
16270
  }
15572
16271
  var defaultContext = {
@@ -16131,6 +16830,9 @@ async function listBackfillSourceFiles(source, options, ctx) {
16131
16830
  if (source.id === "grok-bot") {
16132
16831
  return grokBotBackfillFiles(stringOption(options["source-root"]), resolveHome3(options, ctx), ctx.env, options);
16133
16832
  }
16833
+ if (source.id === "hermes") {
16834
+ return hermesBackfillFiles(stringOption(options["source-root"]), resolveHome3(options, ctx), ctx.env);
16835
+ }
16134
16836
  if (source.id === "pi") {
16135
16837
  return piBackfillFiles(stringOption(options["source-root"]), resolveHome3(options, ctx), ctx.env);
16136
16838
  }
@@ -16138,7 +16840,7 @@ async function listBackfillSourceFiles(source, options, ctx) {
16138
16840
  const fileLists = await Promise.all(roots.map((r) => listJsonlFiles(r)));
16139
16841
  const files = fileLists.flat().sort().slice(0, numberOption(options.limit) || void 0);
16140
16842
  return Promise.all(files.map(async (filePath) => {
16141
- const info = await stat17(filePath);
16843
+ const info = await stat18(filePath);
16142
16844
  return { path: filePath, modifiedAt: info.mtime.toISOString() };
16143
16845
  }));
16144
16846
  }
@@ -16470,13 +17172,13 @@ function selectBackfillFilesForImport(files, watermarkTs) {
16470
17172
  return picked;
16471
17173
  }
16472
17174
  function backfillIncrementalStatePath(home) {
16473
- return path26.join(home, ".vibetime", "backfill-state.json");
17175
+ return path27.join(home, ".vibetime", "backfill-state.json");
16474
17176
  }
16475
17177
  function syncLocalTriggerStatePath(home) {
16476
- return path26.join(home, ".vibetime", "sync-local-trigger.json");
17178
+ return path27.join(home, ".vibetime", "sync-local-trigger.json");
16477
17179
  }
16478
17180
  function syncLocalTriggerLockPath(home) {
16479
- return path26.join(home, ".vibetime", "sync-local-trigger.lock");
17181
+ return path27.join(home, ".vibetime", "sync-local-trigger.lock");
16480
17182
  }
16481
17183
  function backfillRemoteKey(baseUrl) {
16482
17184
  try {
@@ -16538,7 +17240,7 @@ async function readBackfillIncrementalStateFile(home, ctx) {
16538
17240
  }
16539
17241
  async function writeBackfillIncrementalStateFile(home, file) {
16540
17242
  const statePath = backfillIncrementalStatePath(home);
16541
- await mkdir6(path26.dirname(statePath), { recursive: true });
17243
+ await mkdir6(path27.dirname(statePath), { recursive: true });
16542
17244
  await writeFile5(statePath, `${JSON.stringify(file, null, 2)}
16543
17245
  `, "utf8");
16544
17246
  }
@@ -16587,7 +17289,7 @@ async function readSyncLocalTriggerState(statePath) {
16587
17289
  return nextState;
16588
17290
  }
16589
17291
  async function writeSyncLocalTriggerState(statePath, state) {
16590
- await mkdir6(path26.dirname(statePath), { recursive: true });
17292
+ await mkdir6(path27.dirname(statePath), { recursive: true });
16591
17293
  await writeFile5(statePath, `${JSON.stringify(state, null, 2)}
16592
17294
  `, "utf8");
16593
17295
  }
@@ -16602,12 +17304,12 @@ async function readSyncLocalLock(lockPath) {
16602
17304
  return { pid: lock.pid, startedAt: lock.startedAt };
16603
17305
  }
16604
17306
  async function writeSyncLocalLock(lockPath, lock) {
16605
- await mkdir6(path26.dirname(lockPath), { recursive: true });
17307
+ await mkdir6(path27.dirname(lockPath), { recursive: true });
16606
17308
  await writeFile5(lockPath, `${JSON.stringify(lock, null, 2)}
16607
17309
  `, "utf8");
16608
17310
  }
16609
17311
  async function acquireSyncLocalLock(lockPath, lock) {
16610
- await mkdir6(path26.dirname(lockPath), { recursive: true });
17312
+ await mkdir6(path27.dirname(lockPath), { recursive: true });
16611
17313
  try {
16612
17314
  const handle = await open(lockPath, "wx");
16613
17315
  try {
@@ -16687,10 +17389,10 @@ function syncLocalRunnerEntryArgs(cliPath) {
16687
17389
  if (cliPath.endsWith(".ts")) {
16688
17390
  return ["--import", "tsx", cliPath];
16689
17391
  }
16690
- return [path26.resolve(path26.dirname(cliPath), "../bin/vibetime.mjs")];
17392
+ return [path27.resolve(path27.dirname(cliPath), "../bin/vibetime.mjs")];
16691
17393
  }
16692
17394
  function resolveHome3(options, ctx) {
16693
- return path26.resolve(stringOption(options.home) || ctx.env.HOME || os14.homedir());
17395
+ return path27.resolve(stringOption(options.home) || ctx.env.HOME || os14.homedir());
16694
17396
  }
16695
17397
  function requestedTargets(options) {
16696
17398
  const value = options.target || options.targets;