storyforge 0.4.13 → 0.4.15

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.
@@ -6,8 +6,8 @@ import {
6
6
  // src/bridge-poller.ts
7
7
  import { spawn, spawnSync } from "child_process";
8
8
  import * as crypto from "crypto";
9
- var HEARTBEAT_INTERVAL_MS = 3e4;
10
- var POLL_INTERVAL_MS = 3e3;
9
+ var HEARTBEAT_INTERVAL_MS = 6e4;
10
+ var POLL_INTERVAL_MS = 8e3;
11
11
  var CLI_TIMEOUT_MS = Number(process.env.SCRIPT_GEN_TIMEOUT_MS) || 20 * 60 * 1e3;
12
12
  var BridgePoller = class {
13
13
  baseUrl;
@@ -66,7 +66,7 @@ var BridgePoller = class {
66
66
  clientVersion: this.clientVersion,
67
67
  instanceId: this.instanceId
68
68
  }),
69
- signal: AbortSignal.timeout(1e4)
69
+ signal: AbortSignal.timeout(45e3)
70
70
  });
71
71
  if (!resp.ok) {
72
72
  const text = await resp.text().catch(() => "");
@@ -87,7 +87,7 @@ var BridgePoller = class {
87
87
  "Content-Type": "application/json"
88
88
  },
89
89
  body: JSON.stringify({ instanceId: this.instanceId, limit: 3 }),
90
- signal: AbortSignal.timeout(1e4)
90
+ signal: AbortSignal.timeout(45e3)
91
91
  });
92
92
  if (!resp.ok) {
93
93
  if (resp.status === 401) {
@@ -160,7 +160,7 @@ var BridgePoller = class {
160
160
  "Content-Type": "application/json"
161
161
  },
162
162
  body: JSON.stringify({ jobId, ...body }),
163
- signal: AbortSignal.timeout(15e3)
163
+ signal: AbortSignal.timeout(45e3)
164
164
  });
165
165
  if (!resp.ok) {
166
166
  const text = await resp.text().catch(() => "");
@@ -172,34 +172,63 @@ async function gatherCliUsage() {
172
172
  else lines.push(...parsed);
173
173
  }
174
174
  const now = Date.now();
175
+ const cutoff5h = now - 5 * 60 * 60 * 1e3;
175
176
  const cutoff24h = now - 24 * 60 * 60 * 1e3;
177
+ const cutoff7d = now - 7 * 24 * 60 * 60 * 1e3;
176
178
  const startToday = startOfTodayMs(now);
179
+ const messageCounts = { last5h: 0, last24h: 0, last7d: 0, today: 0, lifetime: 0 };
177
180
  const buckets = {
181
+ last5h: {},
178
182
  last24h: {},
183
+ last7d: {},
179
184
  today: {},
180
185
  lifetime: {}
181
186
  };
182
187
  for (const ln of lines) {
183
188
  addUsage(buckets.lifetime, ln.model, ln.delta);
184
- if (ln.ts >= cutoff24h) addUsage(buckets.last24h, ln.model, ln.delta);
185
- if (ln.ts >= startToday) addUsage(buckets.today, ln.model, ln.delta);
189
+ messageCounts.lifetime++;
190
+ if (ln.ts >= cutoff7d) {
191
+ addUsage(buckets.last7d, ln.model, ln.delta);
192
+ messageCounts.last7d++;
193
+ }
194
+ if (ln.ts >= cutoff24h) {
195
+ addUsage(buckets.last24h, ln.model, ln.delta);
196
+ messageCounts.last24h++;
197
+ }
198
+ if (ln.ts >= cutoff5h) {
199
+ addUsage(buckets.last5h, ln.model, ln.delta);
200
+ messageCounts.last5h++;
201
+ }
202
+ if (ln.ts >= startToday) {
203
+ addUsage(buckets.today, ln.model, ln.delta);
204
+ messageCounts.today++;
205
+ }
186
206
  }
187
207
  function finalise(rec) {
188
208
  return Object.values(rec).map(recompute).sort((a, b) => b.costUsd - a.costUsd);
189
209
  }
210
+ const last5h = finalise(buckets.last5h);
190
211
  const last24h = finalise(buckets.last24h);
212
+ const last7d = finalise(buckets.last7d);
191
213
  const today = finalise(buckets.today);
192
214
  const lifetime = finalise(buckets.lifetime);
193
- function sum(rows) {
215
+ function sum(rows, messages) {
194
216
  return {
195
217
  tokens: rows.reduce((s, r) => s + r.inputTokens + r.cachedReadTokens + r.cacheCreateTokens + r.outputTokens, 0),
196
- costUsd: rows.reduce((s, r) => s + r.costUsd, 0)
218
+ costUsd: rows.reduce((s, r) => s + r.costUsd, 0),
219
+ messages
197
220
  };
198
221
  }
199
222
  return {
200
223
  generatedAt: new Date(now).toISOString(),
201
- windows: { last24h, today, lifetime },
202
- totals: { last24h: sum(last24h), today: sum(today), lifetime: sum(lifetime) },
224
+ windows: { last5h, last24h, last7d, today, lifetime },
225
+ totals: {
226
+ last5h: sum(last5h, messageCounts.last5h),
227
+ last24h: sum(last24h, messageCounts.last24h),
228
+ last7d: sum(last7d, messageCounts.last7d),
229
+ today: sum(today, messageCounts.today),
230
+ lifetime: sum(lifetime, messageCounts.lifetime)
231
+ },
203
232
  sources: { claudeFiles: claudeFiles.length, codexFiles: codexFiles.length, skipped }
204
233
  };
205
234
  }
package/dist/index.js CHANGED
@@ -866,7 +866,7 @@ async function devCommand(options) {
866
866
  const pathname = url.pathname;
867
867
  if (pathname === "/api/cli-usage") {
868
868
  try {
869
- const { gatherCliUsage } = await import("./cli-usage-CP4SX57J.js");
869
+ const { gatherCliUsage } = await import("./cli-usage-OFFQXJQN.js");
870
870
  const report = await gatherCliUsage();
871
871
  res.writeHead(200, { ...CORS_HEADERS, "Content-Type": "application/json" });
872
872
  res.end(JSON.stringify(report));
@@ -1596,7 +1596,7 @@ Return ONLY the complete updated TSX. No markdown fences, no explanation.`;
1596
1596
  return "0.0.0";
1597
1597
  })();
1598
1598
  void (async () => {
1599
- const { BridgePoller } = await import("./bridge-poller-YWYLEYOD.js");
1599
+ const { BridgePoller } = await import("./bridge-poller-MCXVVFXL.js");
1600
1600
  const poller = new BridgePoller({ baseUrl: bridgeUrl, token: bridgeToken, clientVersion: `storyforge ${pkgVersion}` });
1601
1601
  poller.start();
1602
1602
  })();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "storyforge",
3
- "version": "0.4.13",
3
+ "version": "0.4.15",
4
4
  "description": "StoryForge — local bridge for the Forge video production web app. Zero runtime dependencies.",
5
5
  "type": "module",
6
6
  "bin": {