@yhong91/vibetime 0.1.2 → 0.1.3

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 +801 -41
  2. package/package.json +1 -1
package/bin/vibetime.mjs CHANGED
@@ -159,9 +159,9 @@ var init_fs = __esm({
159
159
 
160
160
  // src/cli.ts
161
161
  import { spawn } from "node:child_process";
162
- import { mkdir as mkdir4, rename as rename2, rm, stat as stat8, writeFile as writeFile3 } from "node:fs/promises";
162
+ import { mkdir as mkdir4, rename as rename2, rm, stat as stat10, writeFile as writeFile3 } from "node:fs/promises";
163
163
  import os7 from "node:os";
164
- import path16 from "node:path";
164
+ import path18 from "node:path";
165
165
  import { fileURLToPath } from "node:url";
166
166
 
167
167
  // ../shared/src/index.ts
@@ -197,7 +197,7 @@ var TELEMETRY_EVENT_TYPES = [
197
197
  "agent.operation"
198
198
  ];
199
199
  var FILE_ACTIVITY_OPERATIONS = ["read", "search", "create", "write", "edit", "delete"];
200
- var BACKFILL_SOURCE_IDS = ["codex", "claude-code", "claude-cowork", "opencode", "pi", "agy", "codebuddy", "qoder", "qoder-cn"];
200
+ var BACKFILL_SOURCE_IDS = ["codex", "claude-code", "claude-cowork", "opencode", "pi", "agy", "codebuddy", "qoder", "qoder-cn", "workbuddy", "zcode"];
201
201
  function createWorkspaceId(input) {
202
202
  const basis = input.repoUrl || input.repoRoot || input.projectName || "unknown";
203
203
  return `workspace_${fnv1a(basis)}`;
@@ -349,9 +349,9 @@ function removeVolatileHashFields(value) {
349
349
  continue;
350
350
  }
351
351
  if (key === "refs" && isRecord(item)) {
352
- const refs = { ...item };
353
- delete refs.payloadHash;
354
- result[key] = removeVolatileHashFields(refs);
352
+ const refs2 = { ...item };
353
+ delete refs2.payloadHash;
354
+ result[key] = removeVolatileHashFields(refs2);
355
355
  continue;
356
356
  }
357
357
  result[key] = removeVolatileHashFields(item);
@@ -1195,7 +1195,7 @@ function countTextLines(text) {
1195
1195
  }
1196
1196
 
1197
1197
  // src/lib/constants.ts
1198
- var PACKAGE_VERSION = true ? "0.1.2" : "0.1.1";
1198
+ var PACKAGE_VERSION = true ? "0.1.3" : "0.1.1";
1199
1199
  var DEFAULT_API_URL = "http://121.196.224.82:3001";
1200
1200
  var DEFAULT_BACKFILL_BATCH_SIZE = 50;
1201
1201
  var DEFAULT_BACKFILL_BATCH_BYTES = 800 * 1024;
@@ -1224,13 +1224,13 @@ function isPlainObject(value) {
1224
1224
  return value !== null && typeof value === "object" && !Array.isArray(value);
1225
1225
  }
1226
1226
  function stringRefs(value) {
1227
- const refs = {};
1227
+ const refs2 = {};
1228
1228
  for (const [key, item] of Object.entries(value || {})) {
1229
1229
  if (typeof item === "string" && item.length > 0) {
1230
- refs[key] = item;
1230
+ refs2[key] = item;
1231
1231
  }
1232
1232
  }
1233
- return refs;
1233
+ return refs2;
1234
1234
  }
1235
1235
  function stringOption(value) {
1236
1236
  if (Array.isArray(value)) {
@@ -1308,7 +1308,7 @@ function withBackfillRefs(event, context) {
1308
1308
  event.type,
1309
1309
  event.refs?.sourceId
1310
1310
  ]);
1311
- const refs = {
1311
+ const refs2 = {
1312
1312
  ...stringRefs(event.refs),
1313
1313
  importKey,
1314
1314
  sourcePathHash: context.sourcePathHash,
@@ -1318,12 +1318,12 @@ function withBackfillRefs(event, context) {
1318
1318
  parserVersion: PACKAGE_VERSION
1319
1319
  };
1320
1320
  if (context.options.includeSourcePath) {
1321
- refs.transcriptPath = context.filePath;
1321
+ refs2.transcriptPath = context.filePath;
1322
1322
  }
1323
1323
  return {
1324
1324
  ...event,
1325
1325
  id: createStableEventId(importKey),
1326
- refs
1326
+ refs: refs2
1327
1327
  };
1328
1328
  }
1329
1329
  function matchesBackfillFilters(event, options) {
@@ -2956,9 +2956,9 @@ async function parseClaudeCoworkSessionFile(filePath, options) {
2956
2956
  const sessionId = prefixCoworkId(event.sessionId);
2957
2957
  const turnId = prefixCoworkId(event.turnId);
2958
2958
  const workspaceId = createWorkspaceId({ projectName: project, repoRoot: cwd });
2959
- const refs = { ...event.refs };
2959
+ const refs2 = { ...event.refs };
2960
2960
  if (metadata.title) {
2961
- refs.coworkTitleHash = `sha256:${createStableHash(metadata.title)}`;
2961
+ refs2.coworkTitleHash = `sha256:${createStableHash(metadata.title)}`;
2962
2962
  }
2963
2963
  const mapped = {
2964
2964
  ...event,
@@ -2970,7 +2970,7 @@ async function parseClaudeCoworkSessionFile(filePath, options) {
2970
2970
  project,
2971
2971
  sessionId,
2972
2972
  turnId,
2973
- refs
2973
+ refs: refs2
2974
2974
  };
2975
2975
  return rebuildEventIdentity(mapped);
2976
2976
  });
@@ -3507,8 +3507,8 @@ async function codebuddyBackfillFiles(sourceRoot, home, env) {
3507
3507
  }
3508
3508
  const filePath = path8.join(traceDir, entry);
3509
3509
  try {
3510
- const stat9 = await import("node:fs/promises").then((fs) => fs.stat(filePath));
3511
- files.push({ path: filePath, modifiedAt: stat9.mtime.toISOString() });
3510
+ const stat11 = await import("node:fs/promises").then((fs) => fs.stat(filePath));
3511
+ files.push({ path: filePath, modifiedAt: stat11.mtime.toISOString() });
3512
3512
  } catch {
3513
3513
  }
3514
3514
  }
@@ -4513,19 +4513,19 @@ function opencodeDataCandidates(home, env) {
4513
4513
  return [primary, path10.join(home, ".opencode", "opencode.db")];
4514
4514
  }
4515
4515
  async function opencodeBackfillFiles(sourceRoot, home = os4.homedir(), env) {
4516
- const { stat: stat9 } = await import("node:fs/promises");
4516
+ const { stat: stat11 } = await import("node:fs/promises");
4517
4517
  if (sourceRoot) {
4518
4518
  if (!sourceRoot.endsWith(".db")) {
4519
4519
  return [];
4520
4520
  }
4521
- const info = await stat9(sourceRoot).catch(() => null);
4521
+ const info = await stat11(sourceRoot).catch(() => null);
4522
4522
  if (!info) {
4523
4523
  return [];
4524
4524
  }
4525
4525
  return [{ path: sourceRoot, modifiedAt: info.mtime.toISOString() }];
4526
4526
  }
4527
4527
  for (const candidatePath of opencodeDataCandidates(home, env)) {
4528
- const info = await stat9(candidatePath).catch(() => null);
4528
+ const info = await stat11(candidatePath).catch(() => null);
4529
4529
  if (info) {
4530
4530
  return [{ path: candidatePath, modifiedAt: info.mtime.toISOString() }];
4531
4531
  }
@@ -6580,6 +6580,758 @@ function normalizeId(id) {
6580
6580
  return id;
6581
6581
  }
6582
6582
 
6583
+ // src/adapters/workbuddy.ts
6584
+ import { readFile as readFile10, readdir as readdir7, stat as stat7 } from "node:fs/promises";
6585
+ import path14 from "node:path";
6586
+ init_fs();
6587
+ function workbuddyProjectsDir(home, env) {
6588
+ const override = env?.WORKBUDDY_PROJECTS_DIR || env?.WORKBUDDY_HOME;
6589
+ if (override && override.trim()) {
6590
+ return path14.resolve(override, override.endsWith("projects") ? "" : "projects");
6591
+ }
6592
+ return path14.join(home, ".workbuddy", "projects");
6593
+ }
6594
+ function projectFromCwd(cwd, fallback) {
6595
+ if (!cwd) {
6596
+ return fallback;
6597
+ }
6598
+ return path14.basename(cwd) || fallback;
6599
+ }
6600
+ function sourceHash(filePath) {
6601
+ return `sha256:${createStableHash(filePath)}`;
6602
+ }
6603
+ function makeEvent(event, line, filePath, options) {
6604
+ const withRefs = withBackfillRefs(event, {
6605
+ filePath,
6606
+ sourcePathHash: sourceHash(filePath),
6607
+ lineNumber: line.lineNumber,
6608
+ topType: stringField(line.record, "type"),
6609
+ payloadType: stringField(line.record, "role") || stringField(line.record, "name"),
6610
+ options
6611
+ });
6612
+ return validateCanonicalEvent(withRefs).valid ? withRefs : void 0;
6613
+ }
6614
+ function workbuddyUsageMetrics(record) {
6615
+ const providerData = objectField(record, "providerData");
6616
+ const usage = objectField(providerData, "usage");
6617
+ const rawUsage = objectField(providerData, "rawUsage");
6618
+ if (Object.keys(usage).length === 0 && Object.keys(rawUsage).length === 0) {
6619
+ return void 0;
6620
+ }
6621
+ const input = numberField(usage, "inputTokens") ?? numberField(rawUsage, "prompt_tokens") ?? 0;
6622
+ const output = numberField(usage, "outputTokens") ?? numberField(rawUsage, "completion_tokens") ?? 0;
6623
+ const total = numberField(usage, "totalTokens") ?? numberField(rawUsage, "total_tokens") ?? 0;
6624
+ const cacheRead = workbuddyCachedTokens(usage, rawUsage);
6625
+ const cacheCreate = numberField(rawUsage, "cache_creation_input_tokens") ?? numberField(rawUsage, "prompt_cache_write_tokens") ?? 0;
6626
+ const reasoning = workbuddyReasoningTokens(usage, rawUsage);
6627
+ if (!input && !output && !total && !cacheRead && !cacheCreate && !reasoning) {
6628
+ return void 0;
6629
+ }
6630
+ return {
6631
+ tokensInput: input,
6632
+ tokensOutput: output,
6633
+ tokensCachedInput: cacheRead + cacheCreate,
6634
+ tokensCacheCreationInput: cacheCreate,
6635
+ tokensCacheReadInput: cacheRead,
6636
+ tokensReasoningOutput: reasoning,
6637
+ tokensTotal: total || input + output,
6638
+ modelCalls: 1
6639
+ };
6640
+ }
6641
+ function workbuddyCachedTokens(usage, rawUsage) {
6642
+ const rawCache = numberField(rawUsage, "cache_read_input_tokens") ?? numberField(rawUsage, "prompt_cache_hit_tokens") ?? numberField(rawUsage, "cached_tokens");
6643
+ if (rawCache !== void 0) {
6644
+ return rawCache;
6645
+ }
6646
+ const details = usage.inputTokensDetails;
6647
+ if (Array.isArray(details) && isPlainObject(details[0])) {
6648
+ return numberField(details[0], "cached_tokens") || 0;
6649
+ }
6650
+ const rawDetails = objectField(rawUsage, "prompt_tokens_details");
6651
+ return numberField(rawDetails, "cached_tokens") || 0;
6652
+ }
6653
+ function workbuddyReasoningTokens(usage, rawUsage) {
6654
+ const completionDetails = objectField(rawUsage, "completion_tokens_details");
6655
+ const raw = numberField(completionDetails, "reasoning_tokens") ?? numberField(rawUsage, "completion_thinking_tokens");
6656
+ if (raw !== void 0) {
6657
+ return raw;
6658
+ }
6659
+ const details = usage.outputTokensDetails;
6660
+ if (Array.isArray(details) && isPlainObject(details[0])) {
6661
+ return numberField(details[0], "reasoning_tokens") || 0;
6662
+ }
6663
+ return 0;
6664
+ }
6665
+ function contentLength(value) {
6666
+ if (typeof value === "string") {
6667
+ return value.length;
6668
+ }
6669
+ if (Array.isArray(value)) {
6670
+ return value.reduce((total, item) => {
6671
+ if (!isPlainObject(item)) {
6672
+ return total;
6673
+ }
6674
+ return total + (stringField(item, "text") || stringField(item, "input_text") || stringField(item, "output_text") || "").length;
6675
+ }, 0);
6676
+ }
6677
+ return 0;
6678
+ }
6679
+ async function readWorkbuddyLines(filePath) {
6680
+ const text = await readFile10(filePath, "utf8");
6681
+ return text.split(/\r?\n/).map((line, index) => {
6682
+ if (!line.trim()) {
6683
+ return void 0;
6684
+ }
6685
+ try {
6686
+ const record = JSON.parse(line);
6687
+ return isPlainObject(record) ? { lineNumber: index + 1, record } : void 0;
6688
+ } catch {
6689
+ return void 0;
6690
+ }
6691
+ }).filter((line) => Boolean(line));
6692
+ }
6693
+ async function parseWorkbuddySessionFile(filePath, options) {
6694
+ const lines = await readWorkbuddyLines(filePath);
6695
+ if (lines.length === 0) {
6696
+ return [];
6697
+ }
6698
+ const events = [];
6699
+ const first = lines[0].record;
6700
+ const sessionId = stringField(first, "sessionId") || path14.basename(filePath, ".jsonl");
6701
+ const fallbackProject = path14.basename(path14.dirname(filePath));
6702
+ const cwd = lines.map((line) => stringField(line.record, "cwd")).find(Boolean);
6703
+ const project = projectFromCwd(cwd, fallbackProject);
6704
+ const workspaceId = createWorkspaceId({ projectName: project, repoRoot: cwd });
6705
+ const sessionPrefix = `workbuddy:${sessionId}`;
6706
+ const toolStarts = /* @__PURE__ */ new Map();
6707
+ let currentTurnId = `${sessionPrefix}:turn:0`;
6708
+ let turnIndex = 0;
6709
+ const firstTs = lines.map((line) => timestampFrom(numberField(line.record, "timestamp"))).find(Boolean);
6710
+ if (firstTs) {
6711
+ const event = makeEvent({
6712
+ schemaVersion: AGENT_TIME_SCHEMA_VERSION,
6713
+ ts: firstTs,
6714
+ type: "session.started",
6715
+ source: "workbuddy",
6716
+ workspaceId,
6717
+ project,
6718
+ cwd,
6719
+ sessionId: sessionPrefix,
6720
+ agent: "workbuddy",
6721
+ confidence: "derived",
6722
+ refs: { sourceId: `${sessionPrefix}:session` }
6723
+ }, lines[0], filePath, options);
6724
+ if (event) events.push(event);
6725
+ }
6726
+ for (const line of lines) {
6727
+ const record = line.record;
6728
+ const ts = timestampFrom(numberField(record, "timestamp"));
6729
+ if (!ts) {
6730
+ continue;
6731
+ }
6732
+ const type = stringField(record, "type");
6733
+ const sourceId = stringField(record, "id") || `${line.lineNumber}`;
6734
+ if (type === "message" && stringField(record, "role") === "user") {
6735
+ turnIndex += 1;
6736
+ currentTurnId = `${sessionPrefix}:turn:${turnIndex}`;
6737
+ const promptChars = contentLength(record.content);
6738
+ for (const event of [
6739
+ makeEvent({
6740
+ schemaVersion: AGENT_TIME_SCHEMA_VERSION,
6741
+ ts,
6742
+ type: "turn.started",
6743
+ source: "workbuddy",
6744
+ workspaceId,
6745
+ project,
6746
+ cwd,
6747
+ sessionId: sessionPrefix,
6748
+ turnId: currentTurnId,
6749
+ agent: "workbuddy",
6750
+ confidence: "derived",
6751
+ refs: { sourceId: `${sourceId}:turn` }
6752
+ }, line, filePath, options),
6753
+ makeEvent({
6754
+ schemaVersion: AGENT_TIME_SCHEMA_VERSION,
6755
+ ts,
6756
+ type: "prompt.submitted",
6757
+ source: "workbuddy",
6758
+ workspaceId,
6759
+ project,
6760
+ cwd,
6761
+ sessionId: sessionPrefix,
6762
+ turnId: currentTurnId,
6763
+ agent: "workbuddy",
6764
+ metrics: { promptChars, prompts: 1 },
6765
+ confidence: "partial",
6766
+ refs: { sourceId: `${sourceId}:prompt` }
6767
+ }, line, filePath, options)
6768
+ ]) {
6769
+ if (event) events.push(event);
6770
+ }
6771
+ continue;
6772
+ }
6773
+ if (type === "function_call") {
6774
+ const tool = stringField(record, "name");
6775
+ const callId = stringField(record, "callId");
6776
+ if (tool && callId) {
6777
+ toolStarts.set(`${sessionId}:${callId}`, { line, ts, tool, callId });
6778
+ const started = makeEvent({
6779
+ schemaVersion: AGENT_TIME_SCHEMA_VERSION,
6780
+ ts,
6781
+ type: "tool.started",
6782
+ source: "workbuddy",
6783
+ workspaceId,
6784
+ project,
6785
+ cwd,
6786
+ sessionId: sessionPrefix,
6787
+ turnId: currentTurnId,
6788
+ spanId: `${sessionPrefix}:tool:${callId}`,
6789
+ agent: "workbuddy",
6790
+ tool,
6791
+ confidence: "exact",
6792
+ refs: { sourceId: `${callId}:start` }
6793
+ }, line, filePath, options);
6794
+ if (started) events.push(started);
6795
+ }
6796
+ const metrics = workbuddyUsageMetrics(record);
6797
+ const model = stringField(objectField(record, "providerData"), "model");
6798
+ if (metrics || model) {
6799
+ const usage = makeEvent({
6800
+ schemaVersion: AGENT_TIME_SCHEMA_VERSION,
6801
+ ts,
6802
+ type: "model.usage",
6803
+ source: "workbuddy",
6804
+ workspaceId,
6805
+ project,
6806
+ cwd,
6807
+ sessionId: sessionPrefix,
6808
+ turnId: currentTurnId,
6809
+ agent: "workbuddy",
6810
+ model,
6811
+ metrics,
6812
+ confidence: metrics ? "partial" : "derived",
6813
+ refs: { sourceId: `${sourceId}:usage:${callId || line.lineNumber}` }
6814
+ }, line, filePath, options);
6815
+ if (usage) events.push(usage);
6816
+ }
6817
+ continue;
6818
+ }
6819
+ if (type === "function_call_result") {
6820
+ const tool = stringField(record, "name") || "tool";
6821
+ const callId = stringField(record, "callId") || `${line.lineNumber}`;
6822
+ const start = toolStarts.get(`${sessionId}:${callId}`);
6823
+ const durationMs = start?.ts ? Math.max(0, Date.parse(ts) - Date.parse(start.ts)) : void 0;
6824
+ const status = stringField(record, "status");
6825
+ const completed = makeEvent({
6826
+ schemaVersion: AGENT_TIME_SCHEMA_VERSION,
6827
+ ts,
6828
+ type: status === "failed" ? "tool.failed" : "tool.completed",
6829
+ source: "workbuddy",
6830
+ workspaceId,
6831
+ project,
6832
+ cwd,
6833
+ sessionId: sessionPrefix,
6834
+ turnId: currentTurnId,
6835
+ spanId: `${sessionPrefix}:tool:${callId}`,
6836
+ agent: "workbuddy",
6837
+ tool,
6838
+ success: status !== "failed",
6839
+ metrics: { toolDurationMs: durationMs, durationMs },
6840
+ confidence: start ? "derived" : "partial",
6841
+ refs: { sourceId: `${callId}:result` }
6842
+ }, line, filePath, options);
6843
+ if (completed) events.push(completed);
6844
+ }
6845
+ }
6846
+ const lastLine = lines.at(-1);
6847
+ const lastTs = lastLine ? timestampFrom(numberField(lastLine.record, "timestamp")) : void 0;
6848
+ if (lastLine && lastTs) {
6849
+ const event = makeEvent({
6850
+ schemaVersion: AGENT_TIME_SCHEMA_VERSION,
6851
+ ts: lastTs,
6852
+ type: "session.ended",
6853
+ source: "workbuddy",
6854
+ workspaceId,
6855
+ project,
6856
+ cwd,
6857
+ sessionId: sessionPrefix,
6858
+ agent: "workbuddy",
6859
+ confidence: "derived",
6860
+ refs: { sourceId: `${sessionPrefix}:ended` }
6861
+ }, lastLine, filePath, options);
6862
+ if (event) events.push(event);
6863
+ }
6864
+ return events;
6865
+ }
6866
+ async function workbuddyBackfillFiles(sourceRoot, home, env) {
6867
+ const base = sourceRoot || workbuddyProjectsDir(home, env);
6868
+ const files = [];
6869
+ try {
6870
+ const projects = await readdir7(base, { withFileTypes: true });
6871
+ for (const project of projects) {
6872
+ if (!project.isDirectory()) {
6873
+ continue;
6874
+ }
6875
+ const projectDir = path14.join(base, project.name);
6876
+ const entries = await readdir7(projectDir, { withFileTypes: true });
6877
+ for (const entry of entries) {
6878
+ if (entry.isFile() && entry.name.endsWith(".jsonl")) {
6879
+ const filePath = path14.join(projectDir, entry.name);
6880
+ const info = await stat7(filePath);
6881
+ files.push({ path: filePath, modifiedAt: info.mtime.toISOString() });
6882
+ }
6883
+ }
6884
+ }
6885
+ } catch {
6886
+ return [];
6887
+ }
6888
+ return files.sort((a, b) => a.path.localeCompare(b.path));
6889
+ }
6890
+ function createWorkbuddyAdapter() {
6891
+ return {
6892
+ id: "workbuddy",
6893
+ label: "WorkBuddy",
6894
+ agentName: "workbuddy",
6895
+ kind: "agent",
6896
+ detectPath(home, env) {
6897
+ return workbuddyProjectsDir(home, env);
6898
+ },
6899
+ installedPath(home, env) {
6900
+ return workbuddyProjectsDir(home, env);
6901
+ },
6902
+ async isInstalled(home, env) {
6903
+ return pathExists(workbuddyProjectsDir(home, env));
6904
+ },
6905
+ installEntries() {
6906
+ return [];
6907
+ },
6908
+ sourcePaths(home, env) {
6909
+ return [workbuddyProjectsDir(home, env)];
6910
+ },
6911
+ parseSessionFile: parseWorkbuddySessionFile
6912
+ };
6913
+ }
6914
+
6915
+ // src/adapters/zcode.ts
6916
+ import { execFile } from "node:child_process";
6917
+ import { stat as stat8 } from "node:fs/promises";
6918
+ import path15 from "node:path";
6919
+ import { promisify as promisify2 } from "node:util";
6920
+ init_fs();
6921
+ var execFileAsync = promisify2(execFile);
6922
+ function zcodeCliDir(home, env) {
6923
+ const override = env?.ZCODE_CLI_DIR || env?.ZCODE_HOME;
6924
+ if (override && override.trim()) {
6925
+ return path15.resolve(override, override.endsWith("cli") ? "" : "cli");
6926
+ }
6927
+ return path15.join(home, ".zcode", "cli");
6928
+ }
6929
+ function zcodeDbPath(home, env) {
6930
+ return path15.join(zcodeCliDir(home, env), "db", "db.sqlite");
6931
+ }
6932
+ function sourceHash2(filePath) {
6933
+ return `sha256:${createStableHash(filePath)}`;
6934
+ }
6935
+ function projectFromDirectory(directory) {
6936
+ return directory ? path15.basename(directory) || "zcode" : "zcode";
6937
+ }
6938
+ function isoFromMs(value) {
6939
+ return timestampFrom(typeof value === "number" ? value : Number(value));
6940
+ }
6941
+ function makeEvent2(event, row, rowNumber, filePath, options) {
6942
+ const withRefs = withBackfillRefs(event, {
6943
+ filePath,
6944
+ sourcePathHash: sourceHash2(filePath),
6945
+ lineNumber: rowNumber,
6946
+ topType: row.kind,
6947
+ payloadType: stringField(row, "status") || stringField(row, "query_source") || stringField(row, "tool_name"),
6948
+ options
6949
+ });
6950
+ return validateCanonicalEvent(withRefs).valid ? withRefs : void 0;
6951
+ }
6952
+ function refs(values) {
6953
+ const out = {};
6954
+ for (const [key, value] of Object.entries(values)) {
6955
+ if (value !== void 0 && value !== "") {
6956
+ out[key] = String(value);
6957
+ }
6958
+ }
6959
+ return out;
6960
+ }
6961
+ async function sqliteJsonRows(dbPath, sql) {
6962
+ try {
6963
+ const { stdout } = await execFileAsync("sqlite3", ["-readonly", dbPath, sql], {
6964
+ maxBuffer: 32 * 1024 * 1024
6965
+ });
6966
+ return stdout.split(/\r?\n/).map((line) => line.trim()).filter(Boolean).map((line) => {
6967
+ try {
6968
+ const parsed = JSON.parse(line);
6969
+ return isPlainObject(parsed) ? parsed : void 0;
6970
+ } catch {
6971
+ return void 0;
6972
+ }
6973
+ }).filter((row) => Boolean(row));
6974
+ } catch {
6975
+ return [];
6976
+ }
6977
+ }
6978
+ async function readZCodeRows(dbPath) {
6979
+ const queries = [
6980
+ `select json_object(
6981
+ 'kind','session',
6982
+ 'id',id,
6983
+ 'parent_id',parent_id,
6984
+ 'directory',directory,
6985
+ 'title',title,
6986
+ 'task_type',task_type,
6987
+ 'time_created',time_created,
6988
+ 'time_updated',time_updated
6989
+ ) from session order by time_created, id;`,
6990
+ `select json_object(
6991
+ 'kind','turn',
6992
+ 'session_id',session_id,
6993
+ 'turn_id',turn_id,
6994
+ 'status',status,
6995
+ 'started_at',started_at,
6996
+ 'completed_at',completed_at,
6997
+ 'duration_ms',duration_ms,
6998
+ 'model_request_count',model_request_count,
6999
+ 'tool_call_count',tool_call_count,
7000
+ 'input_tokens',input_tokens,
7001
+ 'output_tokens',output_tokens,
7002
+ 'reasoning_tokens',reasoning_tokens,
7003
+ 'cache_creation_input_tokens',cache_creation_input_tokens,
7004
+ 'cache_read_input_tokens',cache_read_input_tokens,
7005
+ 'computed_total_tokens',computed_total_tokens
7006
+ ) from turn_usage order by started_at, session_id, turn_id;`,
7007
+ `select json_object(
7008
+ 'kind','model',
7009
+ 'id',id,
7010
+ 'session_id',session_id,
7011
+ 'turn_id',turn_id,
7012
+ 'query_source',query_source,
7013
+ 'provider_id',provider_id,
7014
+ 'model_id',model_id,
7015
+ 'agent',agent,
7016
+ 'mode',mode,
7017
+ 'status',status,
7018
+ 'started_at',started_at,
7019
+ 'completed_at',completed_at,
7020
+ 'duration_ms',duration_ms,
7021
+ 'input_tokens',input_tokens,
7022
+ 'output_tokens',output_tokens,
7023
+ 'reasoning_tokens',reasoning_tokens,
7024
+ 'cache_creation_input_tokens',cache_creation_input_tokens,
7025
+ 'cache_read_input_tokens',cache_read_input_tokens,
7026
+ 'computed_total_tokens',computed_total_tokens,
7027
+ 'tool_call_count',tool_call_count
7028
+ ) from model_usage order by started_at, id;`,
7029
+ `select json_object(
7030
+ 'kind','tool',
7031
+ 'id',id,
7032
+ 'session_id',session_id,
7033
+ 'turn_id',turn_id,
7034
+ 'tool_call_id',tool_call_id,
7035
+ 'tool_name',tool_name,
7036
+ 'side_effect_scope',side_effect_scope,
7037
+ 'read_only',read_only,
7038
+ 'destructive',destructive,
7039
+ 'approval_status',approval_status,
7040
+ 'status',status,
7041
+ 'started_at',started_at,
7042
+ 'completed_at',completed_at,
7043
+ 'duration_ms',duration_ms,
7044
+ 'output_bytes',output_bytes,
7045
+ 'exit_code',exit_code
7046
+ ) from tool_usage order by started_at, id;`
7047
+ ];
7048
+ const results = await Promise.all(queries.map((query) => sqliteJsonRows(dbPath, query)));
7049
+ return results.flat();
7050
+ }
7051
+ function modelMetrics(row) {
7052
+ const input = numberField(row, "input_tokens") || 0;
7053
+ const output = numberField(row, "output_tokens") || 0;
7054
+ const reasoning = numberField(row, "reasoning_tokens") || 0;
7055
+ const cacheCreation = numberField(row, "cache_creation_input_tokens") || 0;
7056
+ const cacheRead = numberField(row, "cache_read_input_tokens") || 0;
7057
+ const total = numberField(row, "computed_total_tokens") || input + output + reasoning;
7058
+ const durationMs = numberField(row, "duration_ms");
7059
+ return {
7060
+ tokensInput: input,
7061
+ tokensOutput: output,
7062
+ tokensReasoningOutput: reasoning,
7063
+ tokensCachedInput: cacheCreation + cacheRead,
7064
+ tokensCacheCreationInput: cacheCreation,
7065
+ tokensCacheReadInput: cacheRead,
7066
+ tokensTotal: total,
7067
+ modelDurationMs: durationMs,
7068
+ durationMs,
7069
+ modelCalls: 1,
7070
+ toolCalls: numberField(row, "tool_call_count")
7071
+ };
7072
+ }
7073
+ function sessionContext(row, sessions) {
7074
+ const sessionId = stringField(row, "session_id") || stringField(row, "id") || "unknown";
7075
+ const session = sessions.get(sessionId);
7076
+ const cwd = stringField(session, "directory");
7077
+ const project = projectFromDirectory(cwd);
7078
+ return {
7079
+ rawSessionId: sessionId,
7080
+ sessionId: `zcode:${sessionId}`,
7081
+ cwd,
7082
+ project,
7083
+ workspaceId: createWorkspaceId({ projectName: project, repoRoot: cwd }),
7084
+ parentSessionId: stringField(session, "parent_id") ? `zcode:${stringField(session, "parent_id")}` : void 0
7085
+ };
7086
+ }
7087
+ async function parseZCodeDb(filePath, options) {
7088
+ const rows = await readZCodeRows(filePath);
7089
+ if (rows.length === 0) {
7090
+ return [];
7091
+ }
7092
+ const sessions = /* @__PURE__ */ new Map();
7093
+ for (const row of rows) {
7094
+ if (row.kind === "session") {
7095
+ const id = stringField(row, "id");
7096
+ if (id) {
7097
+ sessions.set(id, row);
7098
+ }
7099
+ }
7100
+ }
7101
+ const events = [];
7102
+ rows.forEach((row, index) => {
7103
+ const rowNumber = index + 1;
7104
+ if (row.kind === "session") {
7105
+ const id = stringField(row, "id");
7106
+ const ts = isoFromMs(numberField(row, "time_created"));
7107
+ if (!id || !ts) {
7108
+ return;
7109
+ }
7110
+ const ctx = sessionContext(row, sessions);
7111
+ const event = makeEvent2({
7112
+ schemaVersion: AGENT_TIME_SCHEMA_VERSION,
7113
+ ts,
7114
+ type: "session.started",
7115
+ source: "zcode",
7116
+ workspaceId: ctx.workspaceId,
7117
+ project: ctx.project,
7118
+ cwd: ctx.cwd,
7119
+ sessionId: ctx.sessionId,
7120
+ parentAgentInstanceId: ctx.parentSessionId,
7121
+ agent: "zcode",
7122
+ confidence: "exact",
7123
+ refs: refs({
7124
+ sourceId: `${id}:session`,
7125
+ zcodeTaskType: stringField(row, "task_type"),
7126
+ zcodeTitleHash: stringField(row, "title") ? `sha256:${createStableHash(stringField(row, "title"))}` : void 0
7127
+ })
7128
+ }, row, rowNumber, filePath, options);
7129
+ if (event) events.push(event);
7130
+ const completedTs = isoFromMs(numberField(row, "time_updated"));
7131
+ if (completedTs && completedTs !== ts) {
7132
+ const completed = makeEvent2({
7133
+ schemaVersion: AGENT_TIME_SCHEMA_VERSION,
7134
+ ts: completedTs,
7135
+ type: "session.ended",
7136
+ source: "zcode",
7137
+ workspaceId: ctx.workspaceId,
7138
+ project: ctx.project,
7139
+ cwd: ctx.cwd,
7140
+ sessionId: ctx.sessionId,
7141
+ parentAgentInstanceId: ctx.parentSessionId,
7142
+ agent: "zcode",
7143
+ confidence: "exact",
7144
+ refs: { sourceId: `${id}:session:ended` }
7145
+ }, row, rowNumber, filePath, options);
7146
+ if (completed) events.push(completed);
7147
+ }
7148
+ return;
7149
+ }
7150
+ if (row.kind === "turn") {
7151
+ const rawTurnId = stringField(row, "turn_id");
7152
+ const ts = isoFromMs(numberField(row, "started_at"));
7153
+ if (!rawTurnId || !ts) {
7154
+ return;
7155
+ }
7156
+ const ctx = sessionContext(row, sessions);
7157
+ const turnId = `zcode:${rawTurnId}`;
7158
+ const started = makeEvent2({
7159
+ schemaVersion: AGENT_TIME_SCHEMA_VERSION,
7160
+ ts,
7161
+ type: "turn.started",
7162
+ source: "zcode",
7163
+ workspaceId: ctx.workspaceId,
7164
+ project: ctx.project,
7165
+ cwd: ctx.cwd,
7166
+ sessionId: ctx.sessionId,
7167
+ turnId,
7168
+ agent: "zcode",
7169
+ confidence: "exact",
7170
+ refs: { sourceId: `${rawTurnId}:start` }
7171
+ }, row, rowNumber, filePath, options);
7172
+ if (started) events.push(started);
7173
+ const completedTs = isoFromMs(numberField(row, "completed_at"));
7174
+ if (completedTs) {
7175
+ const status = stringField(row, "status");
7176
+ const completed = makeEvent2({
7177
+ schemaVersion: AGENT_TIME_SCHEMA_VERSION,
7178
+ ts: completedTs,
7179
+ type: "turn.completed",
7180
+ source: "zcode",
7181
+ workspaceId: ctx.workspaceId,
7182
+ project: ctx.project,
7183
+ cwd: ctx.cwd,
7184
+ sessionId: ctx.sessionId,
7185
+ turnId,
7186
+ agent: "zcode",
7187
+ success: status === "completed",
7188
+ metrics: {
7189
+ durationMs: numberField(row, "duration_ms"),
7190
+ turns: 1,
7191
+ modelCalls: numberField(row, "model_request_count"),
7192
+ toolCalls: numberField(row, "tool_call_count")
7193
+ },
7194
+ confidence: "exact",
7195
+ refs: refs({ sourceId: `${rawTurnId}:completed`, zcodeStatus: status })
7196
+ }, row, rowNumber, filePath, options);
7197
+ if (completed) events.push(completed);
7198
+ }
7199
+ return;
7200
+ }
7201
+ if (row.kind === "model") {
7202
+ const ts = isoFromMs(numberField(row, "completed_at")) || isoFromMs(numberField(row, "started_at"));
7203
+ if (!ts) {
7204
+ return;
7205
+ }
7206
+ const ctx = sessionContext(row, sessions);
7207
+ const modelId = stringField(row, "model_id");
7208
+ const usage = makeEvent2({
7209
+ schemaVersion: AGENT_TIME_SCHEMA_VERSION,
7210
+ ts,
7211
+ type: "model.usage",
7212
+ source: "zcode",
7213
+ workspaceId: ctx.workspaceId,
7214
+ project: ctx.project,
7215
+ cwd: ctx.cwd,
7216
+ sessionId: ctx.sessionId,
7217
+ turnId: stringField(row, "turn_id") ? `zcode:${stringField(row, "turn_id")}` : void 0,
7218
+ agent: stringField(row, "agent") || "zcode",
7219
+ provider: stringField(row, "provider_id"),
7220
+ model: modelId,
7221
+ success: stringField(row, "status") === "completed",
7222
+ metrics: modelMetrics(row),
7223
+ confidence: "exact",
7224
+ refs: refs({
7225
+ sourceId: stringField(row, "id") || `${ctx.rawSessionId}:model:${rowNumber}`,
7226
+ zcodeQuerySource: stringField(row, "query_source"),
7227
+ zcodeMode: stringField(row, "mode"),
7228
+ zcodeStatus: stringField(row, "status")
7229
+ })
7230
+ }, row, rowNumber, filePath, options);
7231
+ if (usage) events.push(usage);
7232
+ return;
7233
+ }
7234
+ if (row.kind === "tool") {
7235
+ const startedTs = isoFromMs(numberField(row, "started_at"));
7236
+ const completedTs = isoFromMs(numberField(row, "completed_at")) || startedTs;
7237
+ const tool = stringField(row, "tool_name") || "tool";
7238
+ const toolCallId = stringField(row, "tool_call_id") || stringField(row, "id") || `${rowNumber}`;
7239
+ if (!startedTs) {
7240
+ return;
7241
+ }
7242
+ const ctx = sessionContext(row, sessions);
7243
+ const turnId = stringField(row, "turn_id") ? `zcode:${stringField(row, "turn_id")}` : void 0;
7244
+ const spanId = `${ctx.sessionId}:tool:${toolCallId}`;
7245
+ const started = makeEvent2({
7246
+ schemaVersion: AGENT_TIME_SCHEMA_VERSION,
7247
+ ts: startedTs,
7248
+ type: "tool.started",
7249
+ source: "zcode",
7250
+ workspaceId: ctx.workspaceId,
7251
+ project: ctx.project,
7252
+ cwd: ctx.cwd,
7253
+ sessionId: ctx.sessionId,
7254
+ turnId,
7255
+ spanId,
7256
+ agent: "zcode",
7257
+ tool,
7258
+ confidence: "exact",
7259
+ refs: refs({
7260
+ sourceId: `${toolCallId}:start`,
7261
+ zcodeSideEffectScope: stringField(row, "side_effect_scope"),
7262
+ zcodeApprovalStatus: stringField(row, "approval_status")
7263
+ })
7264
+ }, row, rowNumber, filePath, options);
7265
+ if (started) events.push(started);
7266
+ if (completedTs) {
7267
+ const status = stringField(row, "status");
7268
+ const completed = makeEvent2({
7269
+ schemaVersion: AGENT_TIME_SCHEMA_VERSION,
7270
+ ts: completedTs,
7271
+ type: status === "completed" ? "tool.completed" : "tool.failed",
7272
+ source: "zcode",
7273
+ workspaceId: ctx.workspaceId,
7274
+ project: ctx.project,
7275
+ cwd: ctx.cwd,
7276
+ sessionId: ctx.sessionId,
7277
+ turnId,
7278
+ spanId,
7279
+ agent: "zcode",
7280
+ tool,
7281
+ success: status === "completed",
7282
+ metrics: {
7283
+ toolDurationMs: numberField(row, "duration_ms"),
7284
+ durationMs: numberField(row, "duration_ms"),
7285
+ bytesRead: numberField(row, "output_bytes")
7286
+ },
7287
+ confidence: "exact",
7288
+ refs: refs({
7289
+ sourceId: `${toolCallId}:completed`,
7290
+ zcodeStatus: status,
7291
+ zcodeExitCode: numberField(row, "exit_code")
7292
+ })
7293
+ }, row, rowNumber, filePath, options);
7294
+ if (completed) events.push(completed);
7295
+ }
7296
+ }
7297
+ });
7298
+ return events.sort((a, b) => a.ts.localeCompare(b.ts) || (a.id || "").localeCompare(b.id || ""));
7299
+ }
7300
+ async function zcodeBackfillFiles(sourceRoot, home, env) {
7301
+ const candidate = sourceRoot || zcodeDbPath(home, env);
7302
+ const filePath = candidate.endsWith(".sqlite") ? candidate : path15.join(candidate, "db", "db.sqlite");
7303
+ try {
7304
+ const info = await stat8(filePath);
7305
+ return [{ path: filePath, modifiedAt: info.mtime.toISOString() }];
7306
+ } catch {
7307
+ return [];
7308
+ }
7309
+ }
7310
+ function createZCodeAdapter() {
7311
+ return {
7312
+ id: "zcode",
7313
+ label: "ZCode",
7314
+ agentName: "zcode",
7315
+ kind: "agent",
7316
+ detectPath(home, env) {
7317
+ return zcodeCliDir(home, env);
7318
+ },
7319
+ installedPath(home, env) {
7320
+ return zcodeDbPath(home, env);
7321
+ },
7322
+ async isInstalled(home, env) {
7323
+ return pathExists(zcodeDbPath(home, env));
7324
+ },
7325
+ installEntries() {
7326
+ return [];
7327
+ },
7328
+ sourcePaths(home, env) {
7329
+ return [zcodeDbPath(home, env)];
7330
+ },
7331
+ parseSessionFile: parseZCodeDb
7332
+ };
7333
+ }
7334
+
6583
7335
  // src/lib/pricing.ts
6584
7336
  function estimateEventCostUsd(event) {
6585
7337
  if (event.type !== "model.usage") {
@@ -7016,15 +7768,15 @@ function hookCommandFromGroup(group) {
7016
7768
  import { randomUUID } from "node:crypto";
7017
7769
  import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
7018
7770
  import { homedir, hostname } from "node:os";
7019
- import path14 from "node:path";
7771
+ import path16 from "node:path";
7020
7772
  function configDir(home = homedir()) {
7021
- return path14.join(home, ".vibetime");
7773
+ return path16.join(home, ".vibetime");
7022
7774
  }
7023
7775
  function configPath(home = homedir()) {
7024
- return path14.join(configDir(home), "config.json");
7776
+ return path16.join(configDir(home), "config.json");
7025
7777
  }
7026
7778
  function machineIdPath(home = homedir()) {
7027
- return path14.join(configDir(home), "machine-id");
7779
+ return path16.join(configDir(home), "machine-id");
7028
7780
  }
7029
7781
  function readConfig(home = homedir()) {
7030
7782
  const file = configPath(home);
@@ -7071,15 +7823,15 @@ function defaultMachineName() {
7071
7823
  init_fs();
7072
7824
 
7073
7825
  // src/lib/logger.ts
7074
- import { appendFile, mkdir as mkdir3, rename, stat as stat7 } from "node:fs/promises";
7826
+ import { appendFile, mkdir as mkdir3, rename, stat as stat9 } from "node:fs/promises";
7075
7827
  import { homedir as homedir2 } from "node:os";
7076
- import path15 from "node:path";
7828
+ import path17 from "node:path";
7077
7829
  var MAX_BYTES = 1 * 1024 * 1024;
7078
7830
  function logDir(home = homedir2()) {
7079
- return path15.join(home, ".vibetime", "logs");
7831
+ return path17.join(home, ".vibetime", "logs");
7080
7832
  }
7081
7833
  function logPath(home = homedir2(), name = "cli.log") {
7082
- return path15.join(logDir(home), name);
7834
+ return path17.join(logDir(home), name);
7083
7835
  }
7084
7836
  function serializeError(error) {
7085
7837
  if (error instanceof Error) {
@@ -7089,7 +7841,7 @@ function serializeError(error) {
7089
7841
  }
7090
7842
  async function rotateIfNeeded(file) {
7091
7843
  try {
7092
- const info = await stat7(file);
7844
+ const info = await stat9(file);
7093
7845
  if (info.size > MAX_BYTES) {
7094
7846
  await rename(file, `${file}.1`).catch(() => {
7095
7847
  });
@@ -7254,8 +8006,8 @@ function buildHeaders(token, machine) {
7254
8006
  ...machine?.platform ? { "x-machine-platform": machine.platform } : {}
7255
8007
  };
7256
8008
  }
7257
- function joinUrl(base, path17) {
7258
- return new URL(path17, base.endsWith("/") ? base : `${base}/`).toString();
8009
+ function joinUrl(base, path19) {
8010
+ return new URL(path19, base.endsWith("/") ? base : `${base}/`).toString();
7259
8011
  }
7260
8012
  async function postRollupBatch(remote, rollups, options = {}) {
7261
8013
  const response = await remote.fetchImpl(joinUrl(remote.baseUrl, "/v3/agent/ingest"), {
@@ -7334,6 +8086,8 @@ function createRegistry() {
7334
8086
  registry.register(createCodebuddyAdapter());
7335
8087
  registry.register(createQoderAdapter());
7336
8088
  registry.register(createQoderCnAdapter());
8089
+ registry.register(createWorkbuddyAdapter());
8090
+ registry.register(createZCodeAdapter());
7337
8091
  return registry;
7338
8092
  }
7339
8093
  var defaultContext = {
@@ -7745,11 +8499,17 @@ async function listBackfillSourceFiles(source, options, ctx) {
7745
8499
  if (source.id === "codebuddy") {
7746
8500
  return codebuddyBackfillFiles(stringOption(options["source-root"]), resolveHome2(options, ctx), ctx.env);
7747
8501
  }
8502
+ if (source.id === "workbuddy") {
8503
+ return workbuddyBackfillFiles(stringOption(options["source-root"]), resolveHome2(options, ctx), ctx.env);
8504
+ }
8505
+ if (source.id === "zcode") {
8506
+ return zcodeBackfillFiles(stringOption(options["source-root"]), resolveHome2(options, ctx), ctx.env);
8507
+ }
7748
8508
  const roots = stringOption(options["source-root"]) ? [requiredOption(options, "source-root")] : source.paths;
7749
8509
  const fileLists = await Promise.all(roots.map((r) => listJsonlFiles(r)));
7750
8510
  const files = fileLists.flat().sort().slice(0, numberOption(options.limit) || void 0);
7751
8511
  return Promise.all(files.map(async (filePath) => {
7752
- const info = await stat8(filePath);
8512
+ const info = await stat10(filePath);
7753
8513
  return { path: filePath, modifiedAt: info.mtime.toISOString() };
7754
8514
  }));
7755
8515
  }
@@ -8058,13 +8818,13 @@ function selectBackfillFilesForImport(files, watermarkTs) {
8058
8818
  });
8059
8819
  }
8060
8820
  function backfillIncrementalStatePath(home) {
8061
- return path16.join(home, ".vibetime", "backfill-state.json");
8821
+ return path18.join(home, ".vibetime", "backfill-state.json");
8062
8822
  }
8063
8823
  function syncLocalTriggerStatePath(home) {
8064
- return path16.join(home, ".vibetime", "sync-local-trigger.json");
8824
+ return path18.join(home, ".vibetime", "sync-local-trigger.json");
8065
8825
  }
8066
8826
  function syncLocalTriggerLockPath(home) {
8067
- return path16.join(home, ".vibetime", "sync-local-trigger.lock");
8827
+ return path18.join(home, ".vibetime", "sync-local-trigger.lock");
8068
8828
  }
8069
8829
  async function readBackfillIncrementalState(home, ctx) {
8070
8830
  const statePath = backfillIncrementalStatePath(home);
@@ -8104,7 +8864,7 @@ async function updateBackfillIncrementalState(home, state, selectedFilesBySource
8104
8864
  state.sources[source] = { watermarkTs: latest };
8105
8865
  }
8106
8866
  const statePath = backfillIncrementalStatePath(home);
8107
- await mkdir4(path16.dirname(statePath), { recursive: true });
8867
+ await mkdir4(path18.dirname(statePath), { recursive: true });
8108
8868
  await writeFile3(statePath, `${JSON.stringify(state, null, 2)}
8109
8869
  `, "utf8");
8110
8870
  }
@@ -8137,7 +8897,7 @@ async function readSyncLocalTriggerState(statePath) {
8137
8897
  return nextState;
8138
8898
  }
8139
8899
  async function writeSyncLocalTriggerState(statePath, state) {
8140
- await mkdir4(path16.dirname(statePath), { recursive: true });
8900
+ await mkdir4(path18.dirname(statePath), { recursive: true });
8141
8901
  const tmpPath = `${statePath}.tmp`;
8142
8902
  await writeFile3(tmpPath, `${JSON.stringify(state, null, 2)}
8143
8903
  `, "utf8");
@@ -8154,7 +8914,7 @@ async function readSyncLocalLock(lockPath) {
8154
8914
  return { pid: lock.pid, startedAt: lock.startedAt };
8155
8915
  }
8156
8916
  async function writeSyncLocalLock(lockPath, lock) {
8157
- await mkdir4(path16.dirname(lockPath), { recursive: true });
8917
+ await mkdir4(path18.dirname(lockPath), { recursive: true });
8158
8918
  await writeFile3(lockPath, `${JSON.stringify(lock, null, 2)}
8159
8919
  `, "utf8");
8160
8920
  }
@@ -8214,10 +8974,10 @@ function syncLocalRunnerEntryArgs(cliPath) {
8214
8974
  if (cliPath.endsWith(".ts")) {
8215
8975
  return ["--import", "tsx", cliPath];
8216
8976
  }
8217
- return [path16.resolve(path16.dirname(cliPath), "../bin/vibetime.mjs")];
8977
+ return [path18.resolve(path18.dirname(cliPath), "../bin/vibetime.mjs")];
8218
8978
  }
8219
8979
  function resolveHome2(options, ctx) {
8220
- return path16.resolve(stringOption(options.home) || ctx.env.HOME || os7.homedir());
8980
+ return path18.resolve(stringOption(options.home) || ctx.env.HOME || os7.homedir());
8221
8981
  }
8222
8982
  function requestedTargets(options) {
8223
8983
  const value = options.target || options.targets;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@yhong91/vibetime",
3
3
  "type": "module",
4
- "version": "0.1.2",
4
+ "version": "0.1.3",
5
5
  "description": "vibetime CLI — install AI-agent hooks (Claude Code, Codex, OpenCode, Pi) and report activity to vibetime.",
6
6
  "license": "MIT",
7
7
  "publishConfig": {