@yhong91/vibetime 0.1.14 → 0.1.16

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 +135 -40
  2. package/package.json +1 -1
package/bin/vibetime.mjs CHANGED
@@ -158,7 +158,7 @@ var init_fs = __esm({
158
158
  });
159
159
 
160
160
  // src/cli.ts
161
- import { spawn } from "node:child_process";
161
+ import { spawn, spawnSync } from "node:child_process";
162
162
  import { mkdir as mkdir4, rename as rename2, rm, stat as stat11, writeFile as writeFile3 } from "node:fs/promises";
163
163
  import os8 from "node:os";
164
164
  import path19 from "node:path";
@@ -1195,7 +1195,7 @@ function countTextLines(text) {
1195
1195
  }
1196
1196
 
1197
1197
  // src/lib/constants.ts
1198
- var PACKAGE_VERSION = true ? "0.1.14" : "0.1.1";
1198
+ var PACKAGE_VERSION = true ? "0.1.16" : "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;
@@ -1683,25 +1683,40 @@ function resolveModelName(text) {
1683
1683
  }
1684
1684
  var AGY_USAGE_TIME_MATCH_TOLERANCE_MS = 5 * 60 * 1e3;
1685
1685
  var AGY_RESPONSE_MODEL_ALIASES = {
1686
- "gemini-3-flash-a": "Gemini 3.5 Flash (Medium)",
1687
- "gemini-3-flash-b": "Gemini 3.5 Flash (High)",
1688
- "claude-sonnet-4-6": "Claude Sonnet 4.6 (Thinking)",
1689
- "claude-opus-4-6-thinking": "Claude Opus 4.6 (Thinking)"
1686
+ "gemini-3-flash-a": "Gemini 3.5 Flash",
1687
+ "gemini-3-flash-b": "Gemini 3.5 Flash",
1688
+ "claude-sonnet-4-6": "Claude Sonnet 4.6",
1689
+ "claude-opus-4-6-thinking": "Claude Opus 4.6"
1690
1690
  };
1691
+ var AGY_TIER_PATTERN = /\s*\((Medium|High|Thinking)\)\s*$/i;
1691
1692
  function usageMetadataFromGenerator(item) {
1692
1693
  const usage = item.chatModel?.usage;
1693
1694
  if (!usage) {
1694
1695
  return null;
1695
1696
  }
1696
1697
  const chatModel = item.chatModel;
1697
- const modelDisplayName = typeof chatModel.modelDisplayName === "string" && !chatModel.modelDisplayName.startsWith("MODEL_PLACEHOLDER_") ? chatModel.modelDisplayName : null;
1698
+ const rawDisplayName = typeof chatModel.modelDisplayName === "string" && !chatModel.modelDisplayName.startsWith("MODEL_PLACEHOLDER_") ? chatModel.modelDisplayName : null;
1698
1699
  const responseModel = typeof chatModel.responseModel === "string" && !chatModel.responseModel.startsWith("MODEL_PLACEHOLDER_") ? AGY_RESPONSE_MODEL_ALIASES[chatModel.responseModel] ?? chatModel.responseModel : null;
1699
- const model = modelDisplayName ?? responseModel ?? null;
1700
+ let model = null;
1701
+ let reasoningEffort;
1702
+ if (rawDisplayName) {
1703
+ const tierMatch = rawDisplayName.match(AGY_TIER_PATTERN);
1704
+ if (tierMatch) {
1705
+ model = rawDisplayName.replace(AGY_TIER_PATTERN, "").trim();
1706
+ const tier = tierMatch[1].toLowerCase();
1707
+ reasoningEffort = tier === "thinking" ? "default" : tier;
1708
+ } else {
1709
+ model = rawDisplayName;
1710
+ }
1711
+ } else if (responseModel) {
1712
+ model = responseModel;
1713
+ }
1700
1714
  const occurredAt = Date.parse(chatModel.chatStartMetadata?.createdAt ?? "");
1701
1715
  return {
1702
1716
  usage,
1703
1717
  model,
1704
- occurredAt: Number.isFinite(occurredAt) ? occurredAt : null
1718
+ occurredAt: Number.isFinite(occurredAt) ? occurredAt : null,
1719
+ reasoningEffort
1705
1720
  };
1706
1721
  }
1707
1722
  async function readAgyModelSetting(filePath) {
@@ -1712,7 +1727,8 @@ async function readAgyModelSetting(filePath) {
1712
1727
  stat2(settingsPath)
1713
1728
  ]);
1714
1729
  const configured = JSON.parse(text)?.model;
1715
- const model = typeof configured === "string" ? configured : null;
1730
+ const rawModel = typeof configured === "string" ? configured : null;
1731
+ const model = rawModel ? rawModel.replace(AGY_TIER_PATTERN, "").trim() : null;
1716
1732
  return model ? { model, changedAt: info.mtimeMs } : null;
1717
1733
  } catch {
1718
1734
  return null;
@@ -1938,7 +1954,8 @@ async function parseAgySessionFile(filePath, options) {
1938
1954
  tokensTotal: inputTokens + cacheRead + outputTokens,
1939
1955
  tokensCachedInput: cacheRead || void 0,
1940
1956
  tokensCacheReadInput: cacheRead || void 0,
1941
- tokensReasoningOutput: reasoning || void 0
1957
+ tokensReasoningOutput: reasoning || void 0,
1958
+ reasoningEffort: usageMetadata.reasoningEffort
1942
1959
  }
1943
1960
  }), lineNumber, raw.type);
1944
1961
  } else {
@@ -2101,7 +2118,8 @@ async function parseAgySessionFile(filePath, options) {
2101
2118
  tokensTotal: inputTokens + cacheRead + outputTokens,
2102
2119
  tokensCachedInput: cacheRead || void 0,
2103
2120
  tokensCacheReadInput: cacheRead || void 0,
2104
- tokensReasoningOutput: reasoning || void 0
2121
+ tokensReasoningOutput: reasoning || void 0,
2122
+ reasoningEffort: usageMetadata.reasoningEffort
2105
2123
  }
2106
2124
  }), rawEvents.length + index + 1, "trajectory_metadata");
2107
2125
  }
@@ -5090,40 +5108,50 @@ function opencodePluginContent() {
5090
5108
 
5091
5109
  export const AgentTime = async ({ $, directory }) => {
5092
5110
  const report = async (payload) => {
5111
+ const json = JSON.stringify(payload)
5093
5112
  try {
5094
- await $\`vibetime hook --agent opencode\`.stdin(JSON.stringify(payload)).quiet()
5113
+ await $\`echo \${json} | vibetime hook --agent opencode\`
5095
5114
  } catch {}
5096
5115
  }
5097
5116
 
5098
5117
  return {
5099
- "session.created": async (ctx) => {
5100
- await report({
5101
- hook_event_name: "SessionStart",
5102
- session_id: ctx?.id,
5103
- cwd: directory
5104
- })
5105
- },
5106
- "session.idle": async (ctx) => {
5107
- await report({
5108
- hook_event_name: "SessionEnd",
5109
- session_id: ctx?.id,
5110
- cwd: directory
5111
- })
5112
- },
5113
- "tool.execute.after": async (input) => {
5114
- const toolName = input?.tool || "unknown"
5115
- const toolCallId = input?.toolCallId
5116
- const toolInput = input?.args || input?.input || {}
5117
- const command = toolInput?.command
5118
- const filePath = toolInput?.file_path || toolInput?.filePath
5118
+ event: async ({ event }) => {
5119
+ const type = event?.type
5120
+ const props = event?.properties || {}
5119
5121
 
5120
- await report({
5121
- hook_event_name: "PostToolUse",
5122
- tool_name: toolName,
5123
- tool_use_id: toolCallId,
5124
- cwd: directory,
5125
- tool_input: { command, file_path: filePath }
5126
- })
5122
+ if (type === "session.updated") {
5123
+ const info = props.info || {}
5124
+ await report({
5125
+ hook_event_name: "SessionStart",
5126
+ session_id: props.sessionID || info.id || event?.id,
5127
+ cwd: info.directory || directory
5128
+ })
5129
+ return
5130
+ }
5131
+
5132
+ if (type === "session.idle") {
5133
+ await report({
5134
+ hook_event_name: "SessionEnd",
5135
+ session_id: props.sessionID || event?.id,
5136
+ cwd: directory
5137
+ })
5138
+ return
5139
+ }
5140
+
5141
+ if (type === "message.part.updated") {
5142
+ const part = props.part || {}
5143
+ if (part.type !== "tool") return
5144
+ const state = part.state || {}
5145
+ if (state.status !== "completed") return
5146
+
5147
+ await report({
5148
+ hook_event_name: "PostToolUse",
5149
+ tool_name: part.tool || "unknown",
5150
+ tool_use_id: part.callID || part.id,
5151
+ cwd: directory,
5152
+ tool_input: {}
5153
+ })
5154
+ }
5127
5155
  }
5128
5156
  }
5129
5157
  }
@@ -8755,6 +8783,7 @@ function createCli(ctx, registry) {
8755
8783
  });
8756
8784
  cli.command("detect", "Show supported local targets and install status").action((options) => detectCommand(normalizeOptions(options), ctx, registry).then(() => 0));
8757
8785
  cli.command("install", "Install integration files into detected or requested targets").option("--target <targets>", "Target integrations, comma-separated").option("--targets <targets>", "Target integrations, comma-separated").option("--all", "Install all supported integrations").option("--force", "Overwrite existing non-generated files when needed").action((options) => installCommand(normalizeOptions(options), ctx, registry));
8786
+ cli.command("upgrade", "Check for updates and upgrade to the latest version").option("--check", "Only check for updates, do not install").action((options) => upgradeCommand(normalizeOptions(options), ctx, registry));
8758
8787
  cli.command("hook", "Read agent hook JSON from stdin and report a throttled event").option("--agent <name>", "Agent name").option("--project <name>", "Project name").option("--min-interval <seconds>", "Minimum seconds between similar hook reports").action((options) => hookCommand(normalizeOptions(options), ctx));
8759
8788
  cli.command("sync-local-trigger", "Trigger one background local sync with throttle and locking").option("--min-interval <seconds>", "Minimum seconds between sync triggers").action((options) => syncLocalTriggerCommand(normalizeOptions(options), ctx, registry));
8760
8789
  cli.command("sync-local-runner", "Internal background local sync runner").option("--lock-file <path>", "Lock file for the active sync").option("--state-file <path>", "State file for trigger metadata").action((options) => syncLocalRunnerCommand(normalizeOptions(options), ctx, registry));
@@ -8849,6 +8878,70 @@ async function installCommand(options, ctx, registry) {
8849
8878
  }
8850
8879
  return 0;
8851
8880
  }
8881
+ var NPM_PACKAGE = "@yhong91/vibetime";
8882
+ async function fetchLatestVersion() {
8883
+ try {
8884
+ const response = await fetch(`https://registry.npmjs.org/${NPM_PACKAGE}/latest`, {
8885
+ headers: { Accept: "application/json" },
8886
+ signal: AbortSignal.timeout(1e4)
8887
+ });
8888
+ if (!response.ok) return null;
8889
+ const data = await response.json();
8890
+ return typeof data.version === "string" ? data.version : null;
8891
+ } catch {
8892
+ return null;
8893
+ }
8894
+ }
8895
+ function compareVersions(a, b) {
8896
+ const pa = a.split(".").map(Number);
8897
+ const pb = b.split(".").map(Number);
8898
+ for (let i = 0; i < Math.max(pa.length, pb.length); i++) {
8899
+ const na = pa[i] ?? 0;
8900
+ const nb = pb[i] ?? 0;
8901
+ if (na > nb) return 1;
8902
+ if (na < nb) return -1;
8903
+ }
8904
+ return 0;
8905
+ }
8906
+ async function upgradeCommand(options, ctx, registry) {
8907
+ const current = PACKAGE_VERSION;
8908
+ write(ctx.stdout, `Current version: ${current}
8909
+ `);
8910
+ write(ctx.stdout, "Checking npm registry...\n");
8911
+ const latest = await fetchLatestVersion();
8912
+ if (!latest) {
8913
+ write(ctx.stderr, "Could not fetch latest version from npm. Check your network connection.\n");
8914
+ return 1;
8915
+ }
8916
+ if (compareVersions(current, latest) >= 0) {
8917
+ write(ctx.stdout, `Already up to date (${current}).
8918
+ `);
8919
+ return 0;
8920
+ }
8921
+ write(ctx.stdout, `New version available: ${latest}
8922
+ `);
8923
+ if (options.check) {
8924
+ write(ctx.stdout, `Run \`vibetime upgrade\` to install.
8925
+ `);
8926
+ return 0;
8927
+ }
8928
+ write(ctx.stdout, `Installing ${NPM_PACKAGE}@${latest}...
8929
+
8930
+ `);
8931
+ const result = spawnSync("npm", ["install", "-g", `${NPM_PACKAGE}@latest`], {
8932
+ stdio: "inherit"
8933
+ });
8934
+ if (result.status !== 0) {
8935
+ write(ctx.stderr, "\nFailed to install update. Try manually: npm install -g @yhong91/vibetime@latest\n");
8936
+ return 1;
8937
+ }
8938
+ write(ctx.stdout, "\nRefreshing integration hooks...\n");
8939
+ await installCommand({ ...options, all: true, _: [] }, ctx, registry);
8940
+ write(ctx.stdout, `
8941
+ Upgraded ${current} \u2192 ${latest}
8942
+ `);
8943
+ return 0;
8944
+ }
8852
8945
  async function hookCommand(options, ctx) {
8853
8946
  const home = resolveHome2(options, ctx);
8854
8947
  try {
@@ -9803,6 +9896,7 @@ function helpText() {
9803
9896
  Usage:
9804
9897
  vibetime detect [--json] [--home <path>]
9805
9898
  vibetime install [--target codex,claude,opencode,pi] [--all] [--dry-run] [--force] [--home <path>]
9899
+ vibetime upgrade [--check]
9806
9900
  vibetime hook --agent <name>
9807
9901
  vibetime backfill discover|plan|import|verify --source codex|claude-code|opencode|pi|all --dry-run [--json] [--batch-size <count>]
9808
9902
  vibetime token set <token>
@@ -9816,6 +9910,7 @@ Setup:
9816
9910
  Commands:
9817
9911
  detect Show supported local targets and install status.
9818
9912
  install Install integration files into detected or requested targets.
9913
+ upgrade Check for updates and upgrade to the latest version.
9819
9914
  hook Read agent hook JSON from stdin and report a throttled event.
9820
9915
  backfill Discover local history and create metadata-only import plans.
9821
9916
  token Set, show, or clear the persisted API token.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@yhong91/vibetime",
3
3
  "type": "module",
4
- "version": "0.1.14",
4
+ "version": "0.1.16",
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": {