@cookielab.io/oopst 0.4.0 → 0.4.1

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.
package/dist/index.js CHANGED
@@ -1,541 +1,26 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
3
  const require = createRequire(import.meta.url);
4
- var __create = Object.create;
5
- var __defProp = Object.defineProperty;
6
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
7
- var __getOwnPropNames = Object.getOwnPropertyNames;
8
- var __getProtoOf = Object.getPrototypeOf;
9
- var __hasOwnProp = Object.prototype.hasOwnProperty;
10
- var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
11
- get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
12
- }) : x)(function(x) {
13
- if (typeof require !== "undefined") return require.apply(this, arguments);
14
- throw Error('Dynamic require of "' + x + '" is not supported');
15
- });
16
- var __esm = (fn, res) => function __init() {
17
- return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
18
- };
19
- var __commonJS = (cb, mod) => function __require2() {
20
- return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
21
- };
22
- var __copyProps = (to, from, except, desc2) => {
23
- if (from && typeof from === "object" || typeof from === "function") {
24
- for (let key6 of __getOwnPropNames(from))
25
- if (!__hasOwnProp.call(to, key6) && key6 !== except)
26
- __defProp(to, key6, { get: () => from[key6], enumerable: !(desc2 = __getOwnPropDesc(from, key6)) || desc2.enumerable });
27
- }
28
- return to;
29
- };
30
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
31
- // If the importer is in node compatibility mode or this is not an ESM
32
- // file that has been converted to a CommonJS file using a Babel-
33
- // compatible transform (i.e. "__esModule" has not been set), then set
34
- // "default" to the CommonJS "module.exports" for node compatibility.
35
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
36
- mod
37
- ));
38
-
39
- // ../../node_modules/.pnpm/tsup@8.5.1_jiti@2.7.0_postcss@8.5.15_tsx@4.22.4_typescript@6.0.3_yaml@2.9.0/node_modules/tsup/assets/esm_shims.js
40
- import path from "path";
41
- import { fileURLToPath } from "url";
42
- var getFilename, getDirname, __dirname;
43
- var init_esm_shims = __esm({
44
- "../../node_modules/.pnpm/tsup@8.5.1_jiti@2.7.0_postcss@8.5.15_tsx@4.22.4_typescript@6.0.3_yaml@2.9.0/node_modules/tsup/assets/esm_shims.js"() {
45
- "use strict";
46
- getFilename = () => fileURLToPath(import.meta.url);
47
- getDirname = () => path.dirname(getFilename());
48
- __dirname = /* @__PURE__ */ getDirname();
49
- }
50
- });
51
-
52
- // ../../node_modules/.pnpm/@phc+format@1.0.0/node_modules/@phc/format/index.js
53
- var require_format = __commonJS({
54
- "../../node_modules/.pnpm/@phc+format@1.0.0/node_modules/@phc/format/index.js"(exports, module) {
55
- "use strict";
56
- init_esm_shims();
57
- var idRegex = /^[a-z0-9-]{1,32}$/;
58
- var nameRegex = /^[a-z0-9-]{1,32}$/;
59
- var valueRegex = /^[a-zA-Z0-9/+.-]+$/;
60
- var b64Regex = /^([a-zA-Z0-9/+.-]+|)$/;
61
- var decimalRegex = /^((-)?[1-9]\d*|0)$/;
62
- var versionRegex = /^v=(\d+)$/;
63
- function objToKeyVal(obj) {
64
- return objectKeys(obj).map((k) => [k, obj[k]].join("=")).join(",");
65
- }
66
- function keyValtoObj(str) {
67
- const obj = {};
68
- str.split(",").forEach((ps) => {
69
- const pss = ps.split("=");
70
- if (pss.length < 2) {
71
- throw new TypeError(`params must be in the format name=value`);
72
- }
73
- obj[pss.shift()] = pss.join("=");
74
- });
75
- return obj;
76
- }
77
- function objectKeys(object) {
78
- return Object.keys(object);
79
- }
80
- function objectValues(object) {
81
- if (typeof Object.values === "function") return Object.values(object);
82
- return objectKeys(object).map((k) => object[k]);
83
- }
84
- function serialize(opts) {
85
- const fields = [""];
86
- if (typeof opts !== "object" || opts === null) {
87
- throw new TypeError("opts must be an object");
88
- }
89
- if (typeof opts.id !== "string") {
90
- throw new TypeError("id must be a string");
91
- }
92
- if (!idRegex.test(opts.id)) {
93
- throw new TypeError(`id must satisfy ${idRegex}`);
94
- }
95
- fields.push(opts.id);
96
- if (typeof opts.version !== "undefined") {
97
- if (typeof opts.version !== "number" || opts.version < 0 || !Number.isInteger(opts.version)) {
98
- throw new TypeError("version must be a positive integer number");
99
- }
100
- fields.push(`v=${opts.version}`);
101
- }
102
- if (typeof opts.params !== "undefined") {
103
- if (typeof opts.params !== "object" || opts.params === null) {
104
- throw new TypeError("params must be an object");
105
- }
106
- const pk = objectKeys(opts.params);
107
- if (!pk.every((p) => nameRegex.test(p))) {
108
- throw new TypeError(`params names must satisfy ${nameRegex}`);
109
- }
110
- pk.forEach((k) => {
111
- if (typeof opts.params[k] === "number") {
112
- opts.params[k] = opts.params[k].toString();
113
- } else if (Buffer.isBuffer(opts.params[k])) {
114
- opts.params[k] = opts.params[k].toString("base64").split("=")[0];
115
- }
116
- });
117
- const pv = objectValues(opts.params);
118
- if (!pv.every((v) => typeof v === "string")) {
119
- throw new TypeError("params values must be strings");
120
- }
121
- if (!pv.every((v) => valueRegex.test(v))) {
122
- throw new TypeError(`params values must satisfy ${valueRegex}`);
123
- }
124
- const strpar = objToKeyVal(opts.params);
125
- fields.push(strpar);
126
- }
127
- if (typeof opts.salt !== "undefined") {
128
- if (!Buffer.isBuffer(opts.salt)) {
129
- throw new TypeError("salt must be a Buffer");
130
- }
131
- fields.push(opts.salt.toString("base64").split("=")[0]);
132
- if (typeof opts.hash !== "undefined") {
133
- if (!Buffer.isBuffer(opts.hash)) {
134
- throw new TypeError("hash must be a Buffer");
135
- }
136
- fields.push(opts.hash.toString("base64").split("=")[0]);
137
- }
138
- }
139
- const phcstr = fields.join("$");
140
- return phcstr;
141
- }
142
- function deserialize(phcstr) {
143
- if (typeof phcstr !== "string" || phcstr === "") {
144
- throw new TypeError("pchstr must be a non-empty string");
145
- }
146
- if (phcstr[0] !== "$") {
147
- throw new TypeError("pchstr must contain a $ as first char");
148
- }
149
- const fields = phcstr.split("$");
150
- fields.shift();
151
- let maxf = 5;
152
- if (!versionRegex.test(fields[1])) maxf--;
153
- if (fields.length > maxf) {
154
- throw new TypeError(
155
- `pchstr contains too many fileds: ${fields.length}/${maxf}`
156
- );
157
- }
158
- const id = fields.shift();
159
- if (!idRegex.test(id)) {
160
- throw new TypeError(`id must satisfy ${idRegex}`);
161
- }
162
- let version;
163
- if (versionRegex.test(fields[0])) {
164
- version = parseInt(fields.shift().match(versionRegex)[1], 10);
165
- }
166
- let hash;
167
- let salt;
168
- if (b64Regex.test(fields[fields.length - 1])) {
169
- if (fields.length > 1 && b64Regex.test(fields[fields.length - 2])) {
170
- hash = Buffer.from(fields.pop(), "base64");
171
- salt = Buffer.from(fields.pop(), "base64");
172
- } else {
173
- salt = Buffer.from(fields.pop(), "base64");
174
- }
175
- }
176
- let params;
177
- if (fields.length > 0) {
178
- const parstr = fields.pop();
179
- params = keyValtoObj(parstr);
180
- if (!objectKeys(params).every((p) => nameRegex.test(p))) {
181
- throw new TypeError(`params names must satisfy ${nameRegex}`);
182
- }
183
- const pv = objectValues(params);
184
- if (!pv.every((v) => valueRegex.test(v))) {
185
- throw new TypeError(`params values must satisfy ${valueRegex}`);
186
- }
187
- const pk = objectKeys(params);
188
- pk.forEach((k) => {
189
- params[k] = decimalRegex.test(params[k]) ? parseInt(params[k], 10) : params[k];
190
- });
191
- }
192
- if (fields.length > 0) {
193
- throw new TypeError(`pchstr contains unrecognized fileds: ${fields}`);
194
- }
195
- const phcobj = { id };
196
- if (version) phcobj.version = version;
197
- if (params) phcobj.params = params;
198
- if (salt) phcobj.salt = salt;
199
- if (hash) phcobj.hash = hash;
200
- return phcobj;
201
- }
202
- module.exports = {
203
- serialize,
204
- deserialize
205
- };
206
- }
207
- });
208
-
209
- // ../../node_modules/.pnpm/node-gyp-build@4.8.4/node_modules/node-gyp-build/node-gyp-build.js
210
- var require_node_gyp_build = __commonJS({
211
- "../../node_modules/.pnpm/node-gyp-build@4.8.4/node_modules/node-gyp-build/node-gyp-build.js"(exports, module) {
212
- "use strict";
213
- init_esm_shims();
214
- var fs = __require("fs");
215
- var path2 = __require("path");
216
- var os = __require("os");
217
- var runtimeRequire = typeof __webpack_require__ === "function" ? __non_webpack_require__ : __require;
218
- var vars = process.config && process.config.variables || {};
219
- var prebuildsOnly = !!process.env.PREBUILDS_ONLY;
220
- var abi = process.versions.modules;
221
- var runtime = isElectron() ? "electron" : isNwjs() ? "node-webkit" : "node";
222
- var arch = process.env.npm_config_arch || os.arch();
223
- var platform = process.env.npm_config_platform || os.platform();
224
- var libc = process.env.LIBC || (isAlpine(platform) ? "musl" : "glibc");
225
- var armv = process.env.ARM_VERSION || (arch === "arm64" ? "8" : vars.arm_version) || "";
226
- var uv = (process.versions.uv || "").split(".")[0];
227
- module.exports = load;
228
- function load(dir) {
229
- return runtimeRequire(load.resolve(dir));
230
- }
231
- load.resolve = load.path = function(dir) {
232
- dir = path2.resolve(dir || ".");
233
- try {
234
- var name2 = runtimeRequire(path2.join(dir, "package.json")).name.toUpperCase().replace(/-/g, "_");
235
- if (process.env[name2 + "_PREBUILD"]) dir = process.env[name2 + "_PREBUILD"];
236
- } catch (err) {
237
- }
238
- if (!prebuildsOnly) {
239
- var release = getFirst(path2.join(dir, "build/Release"), matchBuild);
240
- if (release) return release;
241
- var debug = getFirst(path2.join(dir, "build/Debug"), matchBuild);
242
- if (debug) return debug;
243
- }
244
- var prebuild = resolve2(dir);
245
- if (prebuild) return prebuild;
246
- var nearby = resolve2(path2.dirname(process.execPath));
247
- if (nearby) return nearby;
248
- var target = [
249
- "platform=" + platform,
250
- "arch=" + arch,
251
- "runtime=" + runtime,
252
- "abi=" + abi,
253
- "uv=" + uv,
254
- armv ? "armv=" + armv : "",
255
- "libc=" + libc,
256
- "node=" + process.versions.node,
257
- process.versions.electron ? "electron=" + process.versions.electron : "",
258
- typeof __webpack_require__ === "function" ? "webpack=true" : ""
259
- // eslint-disable-line
260
- ].filter(Boolean).join(" ");
261
- throw new Error("No native build was found for " + target + "\n loaded from: " + dir + "\n");
262
- function resolve2(dir2) {
263
- var tuples = readdirSync2(path2.join(dir2, "prebuilds")).map(parseTuple);
264
- var tuple = tuples.filter(matchTuple(platform, arch)).sort(compareTuples)[0];
265
- if (!tuple) return;
266
- var prebuilds = path2.join(dir2, "prebuilds", tuple.name);
267
- var parsed = readdirSync2(prebuilds).map(parseTags);
268
- var candidates = parsed.filter(matchTags(runtime, abi));
269
- var winner = candidates.sort(compareTags(runtime))[0];
270
- if (winner) return path2.join(prebuilds, winner.file);
271
- }
272
- };
273
- function readdirSync2(dir) {
274
- try {
275
- return fs.readdirSync(dir);
276
- } catch (err) {
277
- return [];
278
- }
279
- }
280
- function getFirst(dir, filter) {
281
- var files = readdirSync2(dir).filter(filter);
282
- return files[0] && path2.join(dir, files[0]);
283
- }
284
- function matchBuild(name2) {
285
- return /\.node$/.test(name2);
286
- }
287
- function parseTuple(name2) {
288
- var arr = name2.split("-");
289
- if (arr.length !== 2) return;
290
- var platform2 = arr[0];
291
- var architectures = arr[1].split("+");
292
- if (!platform2) return;
293
- if (!architectures.length) return;
294
- if (!architectures.every(Boolean)) return;
295
- return { name: name2, platform: platform2, architectures };
296
- }
297
- function matchTuple(platform2, arch2) {
298
- return function(tuple) {
299
- if (tuple == null) return false;
300
- if (tuple.platform !== platform2) return false;
301
- return tuple.architectures.includes(arch2);
302
- };
303
- }
304
- function compareTuples(a, b) {
305
- return a.architectures.length - b.architectures.length;
306
- }
307
- function parseTags(file) {
308
- var arr = file.split(".");
309
- var extension = arr.pop();
310
- var tags = { file, specificity: 0 };
311
- if (extension !== "node") return;
312
- for (var i = 0; i < arr.length; i++) {
313
- var tag = arr[i];
314
- if (tag === "node" || tag === "electron" || tag === "node-webkit") {
315
- tags.runtime = tag;
316
- } else if (tag === "napi") {
317
- tags.napi = true;
318
- } else if (tag.slice(0, 3) === "abi") {
319
- tags.abi = tag.slice(3);
320
- } else if (tag.slice(0, 2) === "uv") {
321
- tags.uv = tag.slice(2);
322
- } else if (tag.slice(0, 4) === "armv") {
323
- tags.armv = tag.slice(4);
324
- } else if (tag === "glibc" || tag === "musl") {
325
- tags.libc = tag;
326
- } else {
327
- continue;
328
- }
329
- tags.specificity++;
330
- }
331
- return tags;
332
- }
333
- function matchTags(runtime2, abi2) {
334
- return function(tags) {
335
- if (tags == null) return false;
336
- if (tags.runtime && tags.runtime !== runtime2 && !runtimeAgnostic(tags)) return false;
337
- if (tags.abi && tags.abi !== abi2 && !tags.napi) return false;
338
- if (tags.uv && tags.uv !== uv) return false;
339
- if (tags.armv && tags.armv !== armv) return false;
340
- if (tags.libc && tags.libc !== libc) return false;
341
- return true;
342
- };
343
- }
344
- function runtimeAgnostic(tags) {
345
- return tags.runtime === "node" && tags.napi;
346
- }
347
- function compareTags(runtime2) {
348
- return function(a, b) {
349
- if (a.runtime !== b.runtime) {
350
- return a.runtime === runtime2 ? -1 : 1;
351
- } else if (a.abi !== b.abi) {
352
- return a.abi ? -1 : 1;
353
- } else if (a.specificity !== b.specificity) {
354
- return a.specificity > b.specificity ? -1 : 1;
355
- } else {
356
- return 0;
357
- }
358
- };
359
- }
360
- function isNwjs() {
361
- return !!(process.versions && process.versions.nw);
362
- }
363
- function isElectron() {
364
- if (process.versions && process.versions.electron) return true;
365
- if (process.env.ELECTRON_RUN_AS_NODE) return true;
366
- return typeof window !== "undefined" && window.process && window.process.type === "renderer";
367
- }
368
- function isAlpine(platform2) {
369
- return platform2 === "linux" && fs.existsSync("/etc/alpine-release");
370
- }
371
- load.parseTags = parseTags;
372
- load.matchTags = matchTags;
373
- load.compareTags = compareTags;
374
- load.parseTuple = parseTuple;
375
- load.matchTuple = matchTuple;
376
- load.compareTuples = compareTuples;
377
- }
378
- });
379
-
380
- // ../../node_modules/.pnpm/node-gyp-build@4.8.4/node_modules/node-gyp-build/index.js
381
- var require_node_gyp_build2 = __commonJS({
382
- "../../node_modules/.pnpm/node-gyp-build@4.8.4/node_modules/node-gyp-build/index.js"(exports, module) {
383
- "use strict";
384
- init_esm_shims();
385
- var runtimeRequire = typeof __webpack_require__ === "function" ? __non_webpack_require__ : __require;
386
- if (typeof runtimeRequire.addon === "function") {
387
- module.exports = runtimeRequire.addon.bind(runtimeRequire);
388
- } else {
389
- module.exports = require_node_gyp_build();
390
- }
391
- }
392
- });
393
-
394
- // ../../node_modules/.pnpm/argon2@0.44.0/node_modules/argon2/argon2.cjs
395
- var require_argon2 = __commonJS({
396
- "../../node_modules/.pnpm/argon2@0.44.0/node_modules/argon2/argon2.cjs"(exports, module) {
397
- "use strict";
398
- init_esm_shims();
399
- var { randomBytes: randomBytes2, timingSafeEqual } = __require("crypto");
400
- var { promisify } = __require("util");
401
- var { deserialize, serialize } = require_format();
402
- var gypBuild = require_node_gyp_build2();
403
- var { hash: bindingsHash } = gypBuild(__dirname);
404
- var generateSalt = promisify(randomBytes2);
405
- var argon2d = 0;
406
- var argon2i = 1;
407
- var argon2id = 2;
408
- module.exports.argon2d = argon2d;
409
- module.exports.argon2i = argon2i;
410
- module.exports.argon2id = argon2id;
411
- var types = Object.freeze({ argon2d, argon2i, argon2id });
412
- var names = Object.freeze({
413
- [types.argon2d]: "argon2d",
414
- [types.argon2i]: "argon2i",
415
- [types.argon2id]: "argon2id"
416
- });
417
- var defaults = {
418
- hashLength: 32,
419
- timeCost: 3,
420
- memoryCost: 1 << 16,
421
- parallelism: 4,
422
- type: argon2id,
423
- version: 19
424
- };
425
- async function hash(password, options) {
426
- let { raw, salt, ...rest } = { ...defaults, ...options };
427
- if (rest.hashLength > 2 ** 32 - 1) {
428
- throw new RangeError("Hash length is too large");
429
- }
430
- if (rest.memoryCost > 2 ** 32 - 1) {
431
- throw new RangeError("Memory cost is too large");
432
- }
433
- if (rest.timeCost > 2 ** 32 - 1) {
434
- throw new RangeError("Time cost is too large");
435
- }
436
- if (rest.parallelism > 2 ** 24 - 1) {
437
- throw new RangeError("Parallelism is too large");
438
- }
439
- salt = salt ?? await generateSalt(16);
440
- const {
441
- hashLength,
442
- secret = Buffer.alloc(0),
443
- type,
444
- version,
445
- memoryCost: m,
446
- timeCost: t,
447
- parallelism: p,
448
- associatedData: data = Buffer.alloc(0)
449
- } = rest;
450
- const hash2 = await bindingsHash({
451
- password: Buffer.from(password),
452
- salt,
453
- secret,
454
- data,
455
- hashLength,
456
- m,
457
- t,
458
- p,
459
- version,
460
- type
461
- });
462
- if (raw) {
463
- return hash2;
464
- }
465
- return serialize({
466
- id: names[type],
467
- version,
468
- params: { m, t, p, ...data.byteLength > 0 ? { data } : {} },
469
- salt,
470
- hash: hash2
471
- });
472
- }
473
- module.exports.hash = hash;
474
- function needsRehash(digest, options = {}) {
475
- const { memoryCost, timeCost, parallelism, version } = {
476
- ...defaults,
477
- ...options
478
- };
479
- const {
480
- version: v,
481
- params: { m, t, p }
482
- } = deserialize(digest);
483
- return +v !== +version || +m !== +memoryCost || +t !== +timeCost || +p !== +parallelism;
484
- }
485
- module.exports.needsRehash = needsRehash;
486
- async function verify(digest, password, options = {}) {
487
- const { id, ...rest } = deserialize(digest);
488
- if (!(id in types)) {
489
- return false;
490
- }
491
- const {
492
- version = 16,
493
- params: { m, t, p, data = "" },
494
- salt,
495
- hash: hash2
496
- } = rest;
497
- const { secret = Buffer.alloc(0) } = options;
498
- return timingSafeEqual(
499
- await bindingsHash({
500
- password: Buffer.from(password),
501
- salt,
502
- secret,
503
- data: Buffer.from(data, "base64"),
504
- hashLength: hash2.byteLength,
505
- m: +m,
506
- t: +t,
507
- p: +p,
508
- version: +version,
509
- type: types[id]
510
- }),
511
- hash2
512
- );
513
- }
514
- module.exports.verify = verify;
515
- }
516
- });
517
4
 
518
5
  // src/index.ts
519
- init_esm_shims();
520
6
  import { readFileSync as readFileSync2, realpathSync } from "fs";
521
- import process5 from "process";
522
- import { fileURLToPath as fileURLToPath2 } from "url";
7
+ import process4 from "process";
8
+ import { fileURLToPath } from "url";
523
9
  import { NodeRuntime, NodeServices } from "@effect/platform-node";
524
- import { Effect as Effect23, Layer as Layer13, Option as Option2, Runtime } from "effect";
10
+ import { Effect as Effect17, Layer as Layer8, Option as Option2, Runtime } from "effect";
525
11
  import { CliOutput, Command, Flag } from "effect/unstable/cli";
526
12
 
527
13
  // src/config.ts
528
- init_esm_shims();
529
14
  import { readFileSync } from "fs";
530
15
  import { homedir as readHomedir, hostname as readHostname } from "os";
531
16
  import { isAbsolute, join, normalize, resolve } from "path";
532
- import process2 from "process";
17
+ import process from "process";
533
18
  import { Config, ConfigProvider, Effect, Option, Schema } from "effect";
534
19
  import { parse as parseYaml } from "yaml";
535
20
  var DEFAULT_SERVER_URL = "http://localhost:15433";
536
21
  var DEFAULT_LOOKBACK_DAYS = 2;
537
22
  var USER_CONFIG_FILE = ".oopst.yml";
538
- var runtimeEnv = process2["env"];
23
+ var runtimeEnv = process["env"];
539
24
  var NonEmptyString = Schema.String.check(Schema.isNonEmpty());
540
25
  var NonNegativeInteger = Schema.Number.check(Schema.isInt(), Schema.isGreaterThanOrEqualTo(0));
541
26
  var CliConfigSourceSchema = Schema.Struct({
@@ -563,16 +48,16 @@ var toCliConfigError = (cause) => cause instanceof CliConfigError ? cause : new
563
48
  function userConfigPath(homeDir) {
564
49
  return join(homeDir, USER_CONFIG_FILE);
565
50
  }
566
- function readOptionalConfigFile(path2) {
51
+ function readOptionalConfigFile(path) {
567
52
  try {
568
- return readFileSync(path2, "utf8");
53
+ return readFileSync(path, "utf8");
569
54
  } catch (err) {
570
55
  const code = err instanceof Error && "code" in err ? err.code : void 0;
571
56
  if (code === "ENOENT") {
572
57
  return void 0;
573
58
  }
574
59
  const reason = err instanceof Error ? err.message : String(err);
575
- throw new CliConfigError(`failed to read ${path2}: ${reason}`, { cause: err });
60
+ throw new CliConfigError(`failed to read ${path}: ${reason}`, { cause: err });
576
61
  }
577
62
  }
578
63
  function optionalNonEmpty(value, fieldPath, configPath) {
@@ -627,7 +112,7 @@ function mergeCliConfig(options) {
627
112
  device: optionalNonEmpty(merged.device, "server.device", "CLI"),
628
113
  serverUrl: optionalNonEmpty(merged.api, "server.api", "CLI") ?? DEFAULT_SERVER_URL,
629
114
  lookbackDays: parseLookbackDays(merged.lookbackDays, "sessions.lookbackDays", "CLI"),
630
- exclude: exclude.map((path2) => normalizeConfigPath(path2, options.homeDir)),
115
+ exclude: exclude.map((path) => normalizeConfigPath(path, options.homeDir)),
631
116
  claudeConfigDir: merged.claudeConfigDir,
632
117
  piAgentDir: merged.piAgentDir,
633
118
  piSessionDir: merged.piSessionDir,
@@ -716,17 +201,17 @@ function withoutUndefined(config) {
716
201
  function isRecord(value) {
717
202
  return typeof value === "object" && value !== null && !Array.isArray(value);
718
203
  }
719
- function expandHomePath(path2, homeDir) {
720
- if (path2 === "~") {
204
+ function expandHomePath(path, homeDir) {
205
+ if (path === "~") {
721
206
  return homeDir;
722
207
  }
723
- if (path2.startsWith("~/")) {
724
- return join(homeDir, path2.slice(2));
208
+ if (path.startsWith("~/")) {
209
+ return join(homeDir, path.slice(2));
725
210
  }
726
- return path2;
211
+ return path;
727
212
  }
728
- function normalizeConfigPath(path2, homeDir) {
729
- const expanded = expandHomePath(path2, homeDir);
213
+ function normalizeConfigPath(path, homeDir) {
214
+ const expanded = expandHomePath(path, homeDir);
730
215
  return normalize(isAbsolute(expanded) ? expanded : resolve(homeDir, expanded));
731
216
  }
732
217
  function loadCliConfigEffect(options = {}) {
@@ -769,15 +254,12 @@ function resolveSyncConfig(flags, env) {
769
254
  }
770
255
 
771
256
  // src/services/sync-program.ts
772
- init_esm_shims();
773
- import { Context as Context9, Effect as Effect16, Layer as Layer10 } from "effect";
257
+ import { Context as Context4, Effect as Effect10, Layer as Layer5 } from "effect";
774
258
 
775
259
  // src/sync/run.ts
776
- init_esm_shims();
777
- import { Effect as Effect15 } from "effect";
260
+ import { Effect as Effect9 } from "effect";
778
261
 
779
262
  // src/sync/aggregate.ts
780
- init_esm_shims();
781
263
  import { createHmac } from "crypto";
782
264
  function toIso(hourUtc) {
783
265
  return hourUtc instanceof Date ? hourUtc.toISOString() : hourUtc;
@@ -880,41 +362,68 @@ async function* aggregateUsage(source, options) {
880
362
  }
881
363
  }
882
364
 
883
- // src/sync/client.ts
884
- init_esm_shims();
885
-
886
- // ../../packages/api/src/index.ts
887
- init_esm_shims();
888
-
889
- // ../../packages/api/src/auth/argon.ts
890
- init_esm_shims();
891
- var import_argon2 = __toESM(require_argon2(), 1);
892
- var MEMORY_COST = 65536;
893
- var OPTIONS = {
894
- type: import_argon2.default.argon2id,
895
- memoryCost: MEMORY_COST,
896
- timeCost: 3,
897
- parallelism: 1
365
+ // ../../packages/api/src/errors.ts
366
+ import { Schema as Schema2 } from "effect";
367
+ var ErrorFields = {
368
+ message: Schema2.String
369
+ };
370
+ var UnauthorizedError = class extends Schema2.TaggedErrorClass()("UnauthorizedError", ErrorFields) {
371
+ };
372
+ var ForbiddenError = class extends Schema2.TaggedErrorClass()("ForbiddenError", ErrorFields) {
373
+ };
374
+ var NotFoundError = class extends Schema2.TaggedErrorClass()("NotFoundError", ErrorFields) {
375
+ };
376
+ var ConflictError = class extends Schema2.TaggedErrorClass()("ConflictError", ErrorFields) {
377
+ };
378
+ var ValidationError = class extends Schema2.TaggedErrorClass()("ValidationError", ErrorFields) {
379
+ };
380
+ var RateLimitedError = class extends Schema2.TaggedErrorClass()("RateLimitedError", ErrorFields) {
381
+ };
382
+ var ExternalHttpError = class extends Schema2.TaggedErrorClass()("ExternalHttpError", ErrorFields) {
383
+ };
384
+ var DatabaseError = class extends Schema2.TaggedErrorClass()("DatabaseError", ErrorFields) {
385
+ };
386
+ var AppConfigError = class extends Schema2.TaggedErrorClass()("AppConfigError", ErrorFields) {
387
+ };
388
+ var PricingRefreshError = class extends Schema2.TaggedErrorClass()(
389
+ "PricingRefreshError",
390
+ ErrorFields
391
+ ) {
392
+ };
393
+ var ParserSourceError = class extends Schema2.TaggedErrorClass()("ParserSourceError", ErrorFields) {
394
+ };
395
+ var SyncQuotaExceededError = class extends Schema2.TaggedErrorClass()(
396
+ "SyncQuotaExceededError",
397
+ ErrorFields
398
+ ) {
399
+ };
400
+ var SyncTimestampRejectedError = class extends Schema2.TaggedErrorClass()(
401
+ "SyncTimestampRejectedError",
402
+ ErrorFields
403
+ ) {
898
404
  };
899
405
 
900
- // ../../packages/api/src/auth/sessions.ts
901
- init_esm_shims();
902
- import { Effect as Effect3 } from "effect";
903
-
904
- // ../../packages/api/src/services/session-auth.ts
905
- init_esm_shims();
906
-
907
- // ../../packages/db/src/schema/index.ts
908
- init_esm_shims();
909
-
910
- // ../../packages/db/src/schema/api-token.ts
911
- init_esm_shims();
406
+ // ../../packages/api/src/rpc/auth.ts
407
+ import { Context as Context3, Effect as Effect5, Layer as Layer3, Schema as Schema4 } from "effect";
408
+ import { Rpc, RpcGroup } from "effect/unstable/rpc";
912
409
 
913
- // ../../node_modules/.pnpm/drizzle-orm@1.0.0-rc.3_@effect+sql-pg@4.0.0-beta.92_effect@4.0.0-beta.92__@types+pg@8.2_ddee5fb76746466f3ac889c123576420/node_modules/drizzle-orm/index.js
914
- init_esm_shims();
410
+ // ../../packages/api/src/schemas/auth.ts
411
+ import { Schema as Schema3, SchemaGetter } from "effect";
412
+ var MAX_DISPLAY_NAME_LENGTH = 80;
413
+ var displayNameInput = Schema3.String.check(Schema3.isMaxLength(MAX_DISPLAY_NAME_LENGTH)).pipe(
414
+ Schema3.decodeTo(Schema3.NullOr(Schema3.String), {
415
+ decode: SchemaGetter.transform((value) => {
416
+ const trimmed = value.trim();
417
+ return trimmed.length === 0 ? null : trimmed;
418
+ }),
419
+ encode: SchemaGetter.transform((value) => value ?? "")
420
+ })
421
+ );
422
+ var updateProfileInput = Schema3.Struct({
423
+ displayName: displayNameInput
424
+ });
915
425
 
916
426
  // ../../node_modules/.pnpm/drizzle-orm@1.0.0-rc.3_@effect+sql-pg@4.0.0-beta.92_effect@4.0.0-beta.92__@types+pg@8.2_ddee5fb76746466f3ac889c123576420/node_modules/drizzle-orm/entity.js
917
- init_esm_shims();
918
427
  var entityKind = /* @__PURE__ */ Symbol.for("drizzle:entityKind");
919
428
  function is(value, type) {
920
429
  if (!value || typeof value !== "object") return false;
@@ -929,7 +438,6 @@ function is(value, type) {
929
438
  }
930
439
 
931
440
  // ../../node_modules/.pnpm/drizzle-orm@1.0.0-rc.3_@effect+sql-pg@4.0.0-beta.92_effect@4.0.0-beta.92__@types+pg@8.2_ddee5fb76746466f3ac889c123576420/node_modules/drizzle-orm/subquery.js
932
- init_esm_shims();
933
441
  var Subquery = class {
934
442
  static [entityKind] = "Subquery";
935
443
  constructor(sql2, fields, alias, isWith = false, usedTables = []) {
@@ -947,11 +455,7 @@ var WithSubquery = class extends Subquery {
947
455
  static [entityKind] = "WithSubquery";
948
456
  };
949
457
 
950
- // ../../node_modules/.pnpm/drizzle-orm@1.0.0-rc.3_@effect+sql-pg@4.0.0-beta.92_effect@4.0.0-beta.92__@types+pg@8.2_ddee5fb76746466f3ac889c123576420/node_modules/drizzle-orm/column.js
951
- init_esm_shims();
952
-
953
458
  // ../../node_modules/.pnpm/drizzle-orm@1.0.0-rc.3_@effect+sql-pg@4.0.0-beta.92_effect@4.0.0-beta.92__@types+pg@8.2_ddee5fb76746466f3ac889c123576420/node_modules/drizzle-orm/column-common.js
954
- init_esm_shims();
955
459
  var OriginalColumn = /* @__PURE__ */ Symbol.for("drizzle:OriginalColumn");
956
460
 
957
461
  // ../../node_modules/.pnpm/drizzle-orm@1.0.0-rc.3_@effect+sql-pg@4.0.0-beta.92_effect@4.0.0-beta.92__@types+pg@8.2_ddee5fb76746466f3ac889c123576420/node_modules/drizzle-orm/column.js
@@ -1026,11 +530,7 @@ var Column = class {
1026
530
  }
1027
531
  };
1028
532
 
1029
- // ../../node_modules/.pnpm/drizzle-orm@1.0.0-rc.3_@effect+sql-pg@4.0.0-beta.92_effect@4.0.0-beta.92__@types+pg@8.2_ddee5fb76746466f3ac889c123576420/node_modules/drizzle-orm/table.js
1030
- init_esm_shims();
1031
-
1032
533
  // ../../node_modules/.pnpm/drizzle-orm@1.0.0-rc.3_@effect+sql-pg@4.0.0-beta.92_effect@4.0.0-beta.92__@types+pg@8.2_ddee5fb76746466f3ac889c123576420/node_modules/drizzle-orm/table.utils.js
1033
- init_esm_shims();
1034
534
  var TableName = /* @__PURE__ */ Symbol.for("drizzle:Name");
1035
535
 
1036
536
  // ../../node_modules/.pnpm/drizzle-orm@1.0.0-rc.3_@effect+sql-pg@4.0.0-beta.92_effect@4.0.0-beta.92__@types+pg@8.2_ddee5fb76746466f3ac889c123576420/node_modules/drizzle-orm/table.js
@@ -1089,14 +589,7 @@ var Table = class {
1089
589
  }
1090
590
  };
1091
591
 
1092
- // ../../node_modules/.pnpm/drizzle-orm@1.0.0-rc.3_@effect+sql-pg@4.0.0-beta.92_effect@4.0.0-beta.92__@types+pg@8.2_ddee5fb76746466f3ac889c123576420/node_modules/drizzle-orm/sql/sql.js
1093
- init_esm_shims();
1094
-
1095
- // ../../node_modules/.pnpm/drizzle-orm@1.0.0-rc.3_@effect+sql-pg@4.0.0-beta.92_effect@4.0.0-beta.92__@types+pg@8.2_ddee5fb76746466f3ac889c123576420/node_modules/drizzle-orm/tracing.js
1096
- init_esm_shims();
1097
-
1098
592
  // ../../node_modules/.pnpm/drizzle-orm@1.0.0-rc.3_@effect+sql-pg@4.0.0-beta.92_effect@4.0.0-beta.92__@types+pg@8.2_ddee5fb76746466f3ac889c123576420/node_modules/drizzle-orm/tracing-utils.js
1099
- init_esm_shims();
1100
593
  function iife(fn, ...args) {
1101
594
  return fn(...args);
1102
595
  }
@@ -1107,7 +600,6 @@ var tracer = { startActiveSpan(name2, fn) {
1107
600
  } };
1108
601
 
1109
602
  // ../../node_modules/.pnpm/drizzle-orm@1.0.0-rc.3_@effect+sql-pg@4.0.0-beta.92_effect@4.0.0-beta.92__@types+pg@8.2_ddee5fb76746466f3ac889c123576420/node_modules/drizzle-orm/view-common.js
1110
- init_esm_shims();
1111
603
  var ViewBaseConfig = /* @__PURE__ */ Symbol.for("drizzle:ViewBaseConfig");
1112
604
 
1113
605
  // ../../node_modules/.pnpm/drizzle-orm@1.0.0-rc.3_@effect+sql-pg@4.0.0-beta.92_effect@4.0.0-beta.92__@types+pg@8.2_ddee5fb76746466f3ac889c123576420/node_modules/drizzle-orm/sql/sql.js
@@ -1564,7 +1056,6 @@ Subquery.prototype.getSQL = function() {
1564
1056
  };
1565
1057
 
1566
1058
  // ../../node_modules/.pnpm/drizzle-orm@1.0.0-rc.3_@effect+sql-pg@4.0.0-beta.92_effect@4.0.0-beta.92__@types+pg@8.2_ddee5fb76746466f3ac889c123576420/node_modules/drizzle-orm/sql/expressions/conditions.js
1567
- init_esm_shims();
1568
1059
  function bindIfParam(value, column) {
1569
1060
  if (isDriverValueEncoder(column) && !isSQLWrapper(value) && !is(value, Param) && !is(value, Placeholder) && !is(value, Column) && !is(value, Table) && !is(value, View)) return new Param(value, column);
1570
1061
  return value;
@@ -1572,9 +1063,6 @@ function bindIfParam(value, column) {
1572
1063
  var eq = (left, right) => {
1573
1064
  return sql`${left} = ${bindIfParam(right, left)}`;
1574
1065
  };
1575
- var ne = (left, right) => {
1576
- return sql`${left} <> ${bindIfParam(right, left)}`;
1577
- };
1578
1066
  function and(...unfilteredConditions) {
1579
1067
  const conditions = unfilteredConditions.filter((c) => c !== void 0);
1580
1068
  if (conditions.length === 0) return;
@@ -1588,18 +1076,8 @@ function and(...unfilteredConditions) {
1588
1076
  var gt = (left, right) => {
1589
1077
  return sql`${left} > ${bindIfParam(right, left)}`;
1590
1078
  };
1591
- function isNull(value) {
1592
- return sql`(${value} is null)`;
1593
- }
1594
-
1595
- // ../../node_modules/.pnpm/drizzle-orm@1.0.0-rc.3_@effect+sql-pg@4.0.0-beta.92_effect@4.0.0-beta.92__@types+pg@8.2_ddee5fb76746466f3ac889c123576420/node_modules/drizzle-orm/sql/expressions/select.js
1596
- init_esm_shims();
1597
- function desc(column) {
1598
- return sql`${column} desc`;
1599
- }
1600
1079
 
1601
1080
  // ../../node_modules/.pnpm/drizzle-orm@1.0.0-rc.3_@effect+sql-pg@4.0.0-beta.92_effect@4.0.0-beta.92__@types+pg@8.2_ddee5fb76746466f3ac889c123576420/node_modules/drizzle-orm/utils.js
1602
- init_esm_shims();
1603
1081
  var FnConstructor = Object.getPrototypeOf(() => null).constructor;
1604
1082
  function getColumnNameAndConfig(a, b) {
1605
1083
  return {
@@ -1609,20 +1087,7 @@ function getColumnNameAndConfig(a, b) {
1609
1087
  }
1610
1088
  var textDecoder = typeof TextDecoder === "undefined" ? null : new TextDecoder();
1611
1089
 
1612
- // ../../node_modules/.pnpm/drizzle-orm@1.0.0-rc.3_@effect+sql-pg@4.0.0-beta.92_effect@4.0.0-beta.92__@types+pg@8.2_ddee5fb76746466f3ac889c123576420/node_modules/drizzle-orm/sql/functions/aggregate.js
1613
- init_esm_shims();
1614
- function max(expression) {
1615
- return sql`max(${expression})`.mapWith(is(expression, Column) ? expression : String);
1616
- }
1617
-
1618
- // ../../node_modules/.pnpm/drizzle-orm@1.0.0-rc.3_@effect+sql-pg@4.0.0-beta.92_effect@4.0.0-beta.92__@types+pg@8.2_ddee5fb76746466f3ac889c123576420/node_modules/drizzle-orm/pg-core/index.js
1619
- init_esm_shims();
1620
-
1621
- // ../../node_modules/.pnpm/drizzle-orm@1.0.0-rc.3_@effect+sql-pg@4.0.0-beta.92_effect@4.0.0-beta.92__@types+pg@8.2_ddee5fb76746466f3ac889c123576420/node_modules/drizzle-orm/pg-core/columns/common.js
1622
- init_esm_shims();
1623
-
1624
1090
  // ../../node_modules/.pnpm/drizzle-orm@1.0.0-rc.3_@effect+sql-pg@4.0.0-beta.92_effect@4.0.0-beta.92__@types+pg@8.2_ddee5fb76746466f3ac889c123576420/node_modules/drizzle-orm/pg-core/foreign-keys.js
1625
- init_esm_shims();
1626
1091
  var ForeignKeyBuilder = class {
1627
1092
  static [entityKind] = "PgForeignKeyBuilder";
1628
1093
  /** @internal */
@@ -1956,11 +1421,7 @@ var IndexedColumn = class {
1956
1421
  indexConfig;
1957
1422
  };
1958
1423
 
1959
- // ../../node_modules/.pnpm/drizzle-orm@1.0.0-rc.3_@effect+sql-pg@4.0.0-beta.92_effect@4.0.0-beta.92__@types+pg@8.2_ddee5fb76746466f3ac889c123576420/node_modules/drizzle-orm/pg-core/columns/bigint.js
1960
- init_esm_shims();
1961
-
1962
1424
  // ../../node_modules/.pnpm/drizzle-orm@1.0.0-rc.3_@effect+sql-pg@4.0.0-beta.92_effect@4.0.0-beta.92__@types+pg@8.2_ddee5fb76746466f3ac889c123576420/node_modules/drizzle-orm/pg-core/columns/int.common.js
1963
- init_esm_shims();
1964
1425
  var PgIntColumnBuilder = class extends PgColumnBuilder {
1965
1426
  static [entityKind] = "PgIntColumnBaseBuilder";
1966
1427
  /**
@@ -2062,7 +1523,6 @@ function bigint(a, b) {
2062
1523
  }
2063
1524
 
2064
1525
  // ../../node_modules/.pnpm/drizzle-orm@1.0.0-rc.3_@effect+sql-pg@4.0.0-beta.92_effect@4.0.0-beta.92__@types+pg@8.2_ddee5fb76746466f3ac889c123576420/node_modules/drizzle-orm/pg-core/columns/bigserial.js
2065
- init_esm_shims();
2066
1526
  var PgBigSerial53Builder = class extends PgColumnBuilder {
2067
1527
  static [entityKind] = "PgBigSerial53Builder";
2068
1528
  constructor(name2) {
@@ -2110,7 +1570,6 @@ function bigserial(a, b) {
2110
1570
  }
2111
1571
 
2112
1572
  // ../../node_modules/.pnpm/drizzle-orm@1.0.0-rc.3_@effect+sql-pg@4.0.0-beta.92_effect@4.0.0-beta.92__@types+pg@8.2_ddee5fb76746466f3ac889c123576420/node_modules/drizzle-orm/pg-core/columns/boolean.js
2113
- init_esm_shims();
2114
1573
  var PgBooleanBuilder = class extends PgColumnBuilder {
2115
1574
  static [entityKind] = "PgBooleanBuilder";
2116
1575
  constructor(name2) {
@@ -2134,7 +1593,6 @@ function boolean(name2) {
2134
1593
  }
2135
1594
 
2136
1595
  // ../../node_modules/.pnpm/drizzle-orm@1.0.0-rc.3_@effect+sql-pg@4.0.0-beta.92_effect@4.0.0-beta.92__@types+pg@8.2_ddee5fb76746466f3ac889c123576420/node_modules/drizzle-orm/pg-core/columns/char.js
2137
- init_esm_shims();
2138
1596
  var PgCharBuilder = class extends PgColumnBuilder {
2139
1597
  static [entityKind] = "PgCharBuilder";
2140
1598
  constructor(name2, config) {
@@ -2169,7 +1627,6 @@ function char(a, b = {}) {
2169
1627
  }
2170
1628
 
2171
1629
  // ../../node_modules/.pnpm/drizzle-orm@1.0.0-rc.3_@effect+sql-pg@4.0.0-beta.92_effect@4.0.0-beta.92__@types+pg@8.2_ddee5fb76746466f3ac889c123576420/node_modules/drizzle-orm/pg-core/columns/cidr.js
2172
- init_esm_shims();
2173
1630
  var PgCidrBuilder = class extends PgColumnBuilder {
2174
1631
  static [entityKind] = "PgCidrBuilder";
2175
1632
  constructor(name2) {
@@ -2193,7 +1650,6 @@ function cidr(name2) {
2193
1650
  }
2194
1651
 
2195
1652
  // ../../node_modules/.pnpm/drizzle-orm@1.0.0-rc.3_@effect+sql-pg@4.0.0-beta.92_effect@4.0.0-beta.92__@types+pg@8.2_ddee5fb76746466f3ac889c123576420/node_modules/drizzle-orm/pg-core/array.js
2196
- init_esm_shims();
2197
1653
  function parsePgArrayValue(arrayString, startFrom, inQuotes) {
2198
1654
  for (let i = startFrom; i < arrayString.length; i++) {
2199
1655
  const char2 = arrayString[i];
@@ -2255,14 +1711,7 @@ function makePgArray(array) {
2255
1711
  }).join(",")}}`;
2256
1712
  }
2257
1713
 
2258
- // ../../node_modules/.pnpm/drizzle-orm@1.0.0-rc.3_@effect+sql-pg@4.0.0-beta.92_effect@4.0.0-beta.92__@types+pg@8.2_ddee5fb76746466f3ac889c123576420/node_modules/drizzle-orm/pg-core/columns/custom.js
2259
- init_esm_shims();
2260
-
2261
- // ../../node_modules/.pnpm/drizzle-orm@1.0.0-rc.3_@effect+sql-pg@4.0.0-beta.92_effect@4.0.0-beta.92__@types+pg@8.2_ddee5fb76746466f3ac889c123576420/node_modules/drizzle-orm/pg-core/codecs.js
2262
- init_esm_shims();
2263
-
2264
1714
  // ../../node_modules/.pnpm/drizzle-orm@1.0.0-rc.3_@effect+sql-pg@4.0.0-beta.92_effect@4.0.0-beta.92__@types+pg@8.2_ddee5fb76746466f3ac889c123576420/node_modules/drizzle-orm/pg-core/columns/postgis_extension/utils.js
2265
- init_esm_shims();
2266
1715
  function hexToBytes(hex) {
2267
1716
  const bytes = [];
2268
1717
  for (let c = 0; c < hex.length; c += 2) bytes.push(Number.parseInt(hex.slice(c, c + 2), 16));
@@ -2617,11 +2066,7 @@ function customType(customTypeParams) {
2617
2066
  };
2618
2067
  }
2619
2068
 
2620
- // ../../node_modules/.pnpm/drizzle-orm@1.0.0-rc.3_@effect+sql-pg@4.0.0-beta.92_effect@4.0.0-beta.92__@types+pg@8.2_ddee5fb76746466f3ac889c123576420/node_modules/drizzle-orm/pg-core/columns/date.js
2621
- init_esm_shims();
2622
-
2623
2069
  // ../../node_modules/.pnpm/drizzle-orm@1.0.0-rc.3_@effect+sql-pg@4.0.0-beta.92_effect@4.0.0-beta.92__@types+pg@8.2_ddee5fb76746466f3ac889c123576420/node_modules/drizzle-orm/pg-core/columns/date.common.js
2624
- init_esm_shims();
2625
2070
  var PgDateColumnBuilder = class extends PgColumnBuilder {
2626
2071
  static [entityKind] = "PgDateColumnBaseBuilder";
2627
2072
  /**
@@ -2685,7 +2130,6 @@ function date(a, b) {
2685
2130
  }
2686
2131
 
2687
2132
  // ../../node_modules/.pnpm/drizzle-orm@1.0.0-rc.3_@effect+sql-pg@4.0.0-beta.92_effect@4.0.0-beta.92__@types+pg@8.2_ddee5fb76746466f3ac889c123576420/node_modules/drizzle-orm/pg-core/columns/double-precision.js
2688
- init_esm_shims();
2689
2133
  var PgDoublePrecisionBuilder = class extends PgColumnBuilder {
2690
2134
  static [entityKind] = "PgDoublePrecisionBuilder";
2691
2135
  constructor(name2) {
@@ -2709,7 +2153,6 @@ function doublePrecision(name2) {
2709
2153
  }
2710
2154
 
2711
2155
  // ../../node_modules/.pnpm/drizzle-orm@1.0.0-rc.3_@effect+sql-pg@4.0.0-beta.92_effect@4.0.0-beta.92__@types+pg@8.2_ddee5fb76746466f3ac889c123576420/node_modules/drizzle-orm/pg-core/columns/inet.js
2712
- init_esm_shims();
2713
2156
  var PgInetBuilder = class extends PgColumnBuilder {
2714
2157
  static [entityKind] = "PgInetBuilder";
2715
2158
  constructor(name2) {
@@ -2733,7 +2176,6 @@ function inet(name2) {
2733
2176
  }
2734
2177
 
2735
2178
  // ../../node_modules/.pnpm/drizzle-orm@1.0.0-rc.3_@effect+sql-pg@4.0.0-beta.92_effect@4.0.0-beta.92__@types+pg@8.2_ddee5fb76746466f3ac889c123576420/node_modules/drizzle-orm/pg-core/columns/integer.js
2736
- init_esm_shims();
2737
2179
  var PgIntegerBuilder = class extends PgIntColumnBuilder {
2738
2180
  static [entityKind] = "PgIntegerBuilder";
2739
2181
  constructor(name2) {
@@ -2757,7 +2199,6 @@ function integer(name2) {
2757
2199
  }
2758
2200
 
2759
2201
  // ../../node_modules/.pnpm/drizzle-orm@1.0.0-rc.3_@effect+sql-pg@4.0.0-beta.92_effect@4.0.0-beta.92__@types+pg@8.2_ddee5fb76746466f3ac889c123576420/node_modules/drizzle-orm/pg-core/columns/interval.js
2760
- init_esm_shims();
2761
2202
  var PgIntervalBuilder = class extends PgColumnBuilder {
2762
2203
  static [entityKind] = "PgIntervalBuilder";
2763
2204
  constructor(name2, intervalConfig) {
@@ -2790,7 +2231,6 @@ function interval(a, b = {}) {
2790
2231
  }
2791
2232
 
2792
2233
  // ../../node_modules/.pnpm/drizzle-orm@1.0.0-rc.3_@effect+sql-pg@4.0.0-beta.92_effect@4.0.0-beta.92__@types+pg@8.2_ddee5fb76746466f3ac889c123576420/node_modules/drizzle-orm/pg-core/columns/json.js
2793
- init_esm_shims();
2794
2234
  var PgJsonBuilder = class extends PgColumnBuilder {
2795
2235
  static [entityKind] = "PgJsonBuilder";
2796
2236
  constructor(name2) {
@@ -2817,7 +2257,6 @@ function json(name2) {
2817
2257
  }
2818
2258
 
2819
2259
  // ../../node_modules/.pnpm/drizzle-orm@1.0.0-rc.3_@effect+sql-pg@4.0.0-beta.92_effect@4.0.0-beta.92__@types+pg@8.2_ddee5fb76746466f3ac889c123576420/node_modules/drizzle-orm/pg-core/columns/jsonb.js
2820
- init_esm_shims();
2821
2260
  var PgJsonbBuilder = class extends PgColumnBuilder {
2822
2261
  static [entityKind] = "PgJsonbBuilder";
2823
2262
  constructor(name2) {
@@ -2844,7 +2283,6 @@ function jsonb(name2) {
2844
2283
  }
2845
2284
 
2846
2285
  // ../../node_modules/.pnpm/drizzle-orm@1.0.0-rc.3_@effect+sql-pg@4.0.0-beta.92_effect@4.0.0-beta.92__@types+pg@8.2_ddee5fb76746466f3ac889c123576420/node_modules/drizzle-orm/pg-core/columns/line.js
2847
- init_esm_shims();
2848
2286
  var PgLineBuilder = class extends PgColumnBuilder {
2849
2287
  static [entityKind] = "PgLineBuilder";
2850
2288
  constructor(name2) {
@@ -2896,7 +2334,6 @@ function line(a, b) {
2896
2334
  }
2897
2335
 
2898
2336
  // ../../node_modules/.pnpm/drizzle-orm@1.0.0-rc.3_@effect+sql-pg@4.0.0-beta.92_effect@4.0.0-beta.92__@types+pg@8.2_ddee5fb76746466f3ac889c123576420/node_modules/drizzle-orm/pg-core/columns/macaddr.js
2899
- init_esm_shims();
2900
2337
  var PgMacaddrBuilder = class extends PgColumnBuilder {
2901
2338
  static [entityKind] = "PgMacaddrBuilder";
2902
2339
  constructor(name2) {
@@ -2920,7 +2357,6 @@ function macaddr(name2) {
2920
2357
  }
2921
2358
 
2922
2359
  // ../../node_modules/.pnpm/drizzle-orm@1.0.0-rc.3_@effect+sql-pg@4.0.0-beta.92_effect@4.0.0-beta.92__@types+pg@8.2_ddee5fb76746466f3ac889c123576420/node_modules/drizzle-orm/pg-core/columns/macaddr8.js
2923
- init_esm_shims();
2924
2360
  var PgMacaddr8Builder = class extends PgColumnBuilder {
2925
2361
  static [entityKind] = "PgMacaddr8Builder";
2926
2362
  constructor(name2) {
@@ -2944,7 +2380,6 @@ function macaddr8(name2) {
2944
2380
  }
2945
2381
 
2946
2382
  // ../../node_modules/.pnpm/drizzle-orm@1.0.0-rc.3_@effect+sql-pg@4.0.0-beta.92_effect@4.0.0-beta.92__@types+pg@8.2_ddee5fb76746466f3ac889c123576420/node_modules/drizzle-orm/pg-core/columns/numeric.js
2947
- init_esm_shims();
2948
2383
  var PgNumericBuilder = class extends PgColumnBuilder {
2949
2384
  static [entityKind] = "PgNumericBuilder";
2950
2385
  constructor(name2, precision, scale) {
@@ -3041,7 +2476,6 @@ function numeric(a, b) {
3041
2476
  }
3042
2477
 
3043
2478
  // ../../node_modules/.pnpm/drizzle-orm@1.0.0-rc.3_@effect+sql-pg@4.0.0-beta.92_effect@4.0.0-beta.92__@types+pg@8.2_ddee5fb76746466f3ac889c123576420/node_modules/drizzle-orm/pg-core/columns/point.js
3044
- init_esm_shims();
3045
2479
  var PgPointTupleBuilder = class extends PgColumnBuilder {
3046
2480
  static [entityKind] = "PgPointTupleBuilder";
3047
2481
  constructor(name2) {
@@ -3093,7 +2527,6 @@ function point(a, b) {
3093
2527
  }
3094
2528
 
3095
2529
  // ../../node_modules/.pnpm/drizzle-orm@1.0.0-rc.3_@effect+sql-pg@4.0.0-beta.92_effect@4.0.0-beta.92__@types+pg@8.2_ddee5fb76746466f3ac889c123576420/node_modules/drizzle-orm/pg-core/columns/postgis_extension/geometry.js
3096
- init_esm_shims();
3097
2530
  var PgGeometryBuilder = class extends PgColumnBuilder {
3098
2531
  static [entityKind] = "PgGeometryBuilder";
3099
2532
  constructor(name2, srid) {
@@ -3149,7 +2582,6 @@ function geometry(a, b) {
3149
2582
  }
3150
2583
 
3151
2584
  // ../../node_modules/.pnpm/drizzle-orm@1.0.0-rc.3_@effect+sql-pg@4.0.0-beta.92_effect@4.0.0-beta.92__@types+pg@8.2_ddee5fb76746466f3ac889c123576420/node_modules/drizzle-orm/pg-core/columns/real.js
3152
- init_esm_shims();
3153
2585
  var PgRealBuilder = class extends PgColumnBuilder {
3154
2586
  static [entityKind] = "PgRealBuilder";
3155
2587
  constructor(name2, length) {
@@ -3177,7 +2609,6 @@ function real(name2) {
3177
2609
  }
3178
2610
 
3179
2611
  // ../../node_modules/.pnpm/drizzle-orm@1.0.0-rc.3_@effect+sql-pg@4.0.0-beta.92_effect@4.0.0-beta.92__@types+pg@8.2_ddee5fb76746466f3ac889c123576420/node_modules/drizzle-orm/pg-core/columns/serial.js
3180
- init_esm_shims();
3181
2612
  var PgSerialBuilder = class extends PgColumnBuilder {
3182
2613
  static [entityKind] = "PgSerialBuilder";
3183
2614
  constructor(name2) {
@@ -3203,7 +2634,6 @@ function serial(name2) {
3203
2634
  }
3204
2635
 
3205
2636
  // ../../node_modules/.pnpm/drizzle-orm@1.0.0-rc.3_@effect+sql-pg@4.0.0-beta.92_effect@4.0.0-beta.92__@types+pg@8.2_ddee5fb76746466f3ac889c123576420/node_modules/drizzle-orm/pg-core/columns/smallint.js
3206
- init_esm_shims();
3207
2637
  var PgSmallIntBuilder = class extends PgIntColumnBuilder {
3208
2638
  static [entityKind] = "PgSmallIntBuilder";
3209
2639
  constructor(name2) {
@@ -3227,7 +2657,6 @@ function smallint(name2) {
3227
2657
  }
3228
2658
 
3229
2659
  // ../../node_modules/.pnpm/drizzle-orm@1.0.0-rc.3_@effect+sql-pg@4.0.0-beta.92_effect@4.0.0-beta.92__@types+pg@8.2_ddee5fb76746466f3ac889c123576420/node_modules/drizzle-orm/pg-core/columns/smallserial.js
3230
- init_esm_shims();
3231
2660
  var PgSmallSerialBuilder = class extends PgColumnBuilder {
3232
2661
  static [entityKind] = "PgSmallSerialBuilder";
3233
2662
  constructor(name2) {
@@ -3253,7 +2682,6 @@ function smallserial(name2) {
3253
2682
  }
3254
2683
 
3255
2684
  // ../../node_modules/.pnpm/drizzle-orm@1.0.0-rc.3_@effect+sql-pg@4.0.0-beta.92_effect@4.0.0-beta.92__@types+pg@8.2_ddee5fb76746466f3ac889c123576420/node_modules/drizzle-orm/pg-core/columns/text.js
3256
- init_esm_shims();
3257
2685
  var PgTextBuilder = class extends PgColumnBuilder {
3258
2686
  static [entityKind] = "PgTextBuilder";
3259
2687
  constructor(name2, config) {
@@ -3284,7 +2712,6 @@ function text(a, b = {}) {
3284
2712
  }
3285
2713
 
3286
2714
  // ../../node_modules/.pnpm/drizzle-orm@1.0.0-rc.3_@effect+sql-pg@4.0.0-beta.92_effect@4.0.0-beta.92__@types+pg@8.2_ddee5fb76746466f3ac889c123576420/node_modules/drizzle-orm/pg-core/columns/time.js
3287
- init_esm_shims();
3288
2715
  var PgTimeBuilder = class extends PgDateColumnBuilder {
3289
2716
  static [entityKind] = "PgTimeBuilder";
3290
2717
  constructor(name2, withTimezone, precision) {
@@ -3320,7 +2747,6 @@ function time(a, b = {}) {
3320
2747
  }
3321
2748
 
3322
2749
  // ../../node_modules/.pnpm/drizzle-orm@1.0.0-rc.3_@effect+sql-pg@4.0.0-beta.92_effect@4.0.0-beta.92__@types+pg@8.2_ddee5fb76746466f3ac889c123576420/node_modules/drizzle-orm/pg-core/columns/timestamp.js
3323
- init_esm_shims();
3324
2750
  var PgTimestampBuilder = class extends PgDateColumnBuilder {
3325
2751
  static [entityKind] = "PgTimestampBuilder";
3326
2752
  constructor(name2, withTimezone, precision) {
@@ -3392,7 +2818,6 @@ function timestamp(a, b = {}) {
3392
2818
  }
3393
2819
 
3394
2820
  // ../../node_modules/.pnpm/drizzle-orm@1.0.0-rc.3_@effect+sql-pg@4.0.0-beta.92_effect@4.0.0-beta.92__@types+pg@8.2_ddee5fb76746466f3ac889c123576420/node_modules/drizzle-orm/pg-core/columns/uuid.js
3395
- init_esm_shims();
3396
2821
  var PgUUIDBuilder = class extends PgColumnBuilder {
3397
2822
  static [entityKind] = "PgUUIDBuilder";
3398
2823
  constructor(name2) {
@@ -3422,7 +2847,6 @@ function uuid(name2) {
3422
2847
  }
3423
2848
 
3424
2849
  // ../../node_modules/.pnpm/drizzle-orm@1.0.0-rc.3_@effect+sql-pg@4.0.0-beta.92_effect@4.0.0-beta.92__@types+pg@8.2_ddee5fb76746466f3ac889c123576420/node_modules/drizzle-orm/pg-core/columns/varchar.js
3425
- init_esm_shims();
3426
2850
  var PgVarcharBuilder = class extends PgColumnBuilder {
3427
2851
  static [entityKind] = "PgVarcharBuilder";
3428
2852
  constructor(name2, config) {
@@ -3454,7 +2878,6 @@ function varchar(a, b = {}) {
3454
2878
  }
3455
2879
 
3456
2880
  // ../../node_modules/.pnpm/drizzle-orm@1.0.0-rc.3_@effect+sql-pg@4.0.0-beta.92_effect@4.0.0-beta.92__@types+pg@8.2_ddee5fb76746466f3ac889c123576420/node_modules/drizzle-orm/pg-core/columns/vector_extension/bit.js
3457
- init_esm_shims();
3458
2881
  var PgBinaryVectorBuilder = class extends PgColumnBuilder {
3459
2882
  static [entityKind] = "PgBinaryVectorBuilder";
3460
2883
  constructor(name2, config) {
@@ -3481,7 +2904,6 @@ function bit(a, b) {
3481
2904
  }
3482
2905
 
3483
2906
  // ../../node_modules/.pnpm/drizzle-orm@1.0.0-rc.3_@effect+sql-pg@4.0.0-beta.92_effect@4.0.0-beta.92__@types+pg@8.2_ddee5fb76746466f3ac889c123576420/node_modules/drizzle-orm/pg-core/columns/vector_extension/halfvec.js
3484
- init_esm_shims();
3485
2907
  var PgHalfVectorBuilder = class extends PgColumnBuilder {
3486
2908
  static [entityKind] = "PgHalfVectorBuilder";
3487
2909
  constructor(name2, config) {
@@ -3511,7 +2933,6 @@ function halfvec(a, b) {
3511
2933
  }
3512
2934
 
3513
2935
  // ../../node_modules/.pnpm/drizzle-orm@1.0.0-rc.3_@effect+sql-pg@4.0.0-beta.92_effect@4.0.0-beta.92__@types+pg@8.2_ddee5fb76746466f3ac889c123576420/node_modules/drizzle-orm/pg-core/columns/vector_extension/sparsevec.js
3514
- init_esm_shims();
3515
2936
  var PgSparseVectorBuilder = class extends PgColumnBuilder {
3516
2937
  static [entityKind] = "PgSparseVectorBuilder";
3517
2938
  constructor(name2, config) {
@@ -3538,7 +2959,6 @@ function sparsevec(a, b) {
3538
2959
  }
3539
2960
 
3540
2961
  // ../../node_modules/.pnpm/drizzle-orm@1.0.0-rc.3_@effect+sql-pg@4.0.0-beta.92_effect@4.0.0-beta.92__@types+pg@8.2_ddee5fb76746466f3ac889c123576420/node_modules/drizzle-orm/pg-core/columns/vector_extension/vector.js
3541
- init_esm_shims();
3542
2962
  var PgVectorBuilder = class extends PgColumnBuilder {
3543
2963
  static [entityKind] = "PgVectorBuilder";
3544
2964
  constructor(name2, config) {
@@ -3567,11 +2987,7 @@ function vector(a, b) {
3567
2987
  return new PgVectorBuilder(name2, config);
3568
2988
  }
3569
2989
 
3570
- // ../../node_modules/.pnpm/drizzle-orm@1.0.0-rc.3_@effect+sql-pg@4.0.0-beta.92_effect@4.0.0-beta.92__@types+pg@8.2_ddee5fb76746466f3ac889c123576420/node_modules/drizzle-orm/pg-core/table.js
3571
- init_esm_shims();
3572
-
3573
2990
  // ../../node_modules/.pnpm/drizzle-orm@1.0.0-rc.3_@effect+sql-pg@4.0.0-beta.92_effect@4.0.0-beta.92__@types+pg@8.2_ddee5fb76746466f3ac889c123576420/node_modules/drizzle-orm/pg-core/columns/all.js
3574
- init_esm_shims();
3575
2991
  function getPgColumnBuilders() {
3576
2992
  return {
3577
2993
  bigint,
@@ -3610,7 +3026,6 @@ function getPgColumnBuilders() {
3610
3026
  }
3611
3027
 
3612
3028
  // ../../node_modules/.pnpm/drizzle-orm@1.0.0-rc.3_@effect+sql-pg@4.0.0-beta.92_effect@4.0.0-beta.92__@types+pg@8.2_ddee5fb76746466f3ac889c123576420/node_modules/drizzle-orm/casing.js
3613
- init_esm_shims();
3614
3029
  function toSnakeCase(input) {
3615
3030
  return (input.replace(/['\u2019]/g, "").match(/[\da-z]+|[A-Z]+(?![a-z])|[A-Z][\da-z]+/g) ?? []).map((word) => word.toLowerCase()).join("_");
3616
3031
  }
@@ -3683,7 +3098,6 @@ function pgTableWithCasing(casing) {
3683
3098
  var pgTable = pgTableWithCasing(void 0);
3684
3099
 
3685
3100
  // ../../node_modules/.pnpm/drizzle-orm@1.0.0-rc.3_@effect+sql-pg@4.0.0-beta.92_effect@4.0.0-beta.92__@types+pg@8.2_ddee5fb76746466f3ac889c123576420/node_modules/drizzle-orm/pg-core/primary-keys.js
3686
- init_esm_shims();
3687
3101
  function primaryKey(...config) {
3688
3102
  if (config[0].columns) return new PrimaryKeyBuilder(config[0].columns, config[0].name);
3689
3103
  return new PrimaryKeyBuilder(config);
@@ -3720,11 +3134,10 @@ var PrimaryKey = class {
3720
3134
  };
3721
3135
 
3722
3136
  // ../../node_modules/.pnpm/drizzle-orm@1.0.0-rc.3_@effect+sql-pg@4.0.0-beta.92_effect@4.0.0-beta.92__@types+pg@8.2_ddee5fb76746466f3ac889c123576420/node_modules/drizzle-orm/pg-core/indexes.js
3723
- init_esm_shims();
3724
3137
  var IndexBuilderOn = class {
3725
3138
  static [entityKind] = "PgIndexBuilderOn";
3726
- constructor(unique2, name2) {
3727
- this.unique = unique2;
3139
+ constructor(unique, name2) {
3140
+ this.unique = unique;
3728
3141
  this.name = name2;
3729
3142
  }
3730
3143
  on(...columns) {
@@ -3779,11 +3192,11 @@ var IndexBuilder = class {
3779
3192
  static [entityKind] = "PgIndexBuilder";
3780
3193
  /** @internal */
3781
3194
  config;
3782
- constructor(columns, unique2, only, name2, method = "btree") {
3195
+ constructor(columns, unique, only, name2, method = "btree") {
3783
3196
  this.config = {
3784
3197
  name: name2,
3785
3198
  columns,
3786
- unique: unique2,
3199
+ unique,
3787
3200
  only,
3788
3201
  method
3789
3202
  };
@@ -3825,7 +3238,6 @@ function uniqueIndex(name2) {
3825
3238
  }
3826
3239
 
3827
3240
  // ../../packages/db/src/schema/user.ts
3828
- init_esm_shims();
3829
3241
  var userTable = pgTable("user", {
3830
3242
  id: uuid("id").primaryKey().default(sql`uuidv7()`),
3831
3243
  email: text("email").notNull().unique(),
@@ -3847,7 +3259,6 @@ var apiTokenTable = pgTable("api_token", {
3847
3259
  });
3848
3260
 
3849
3261
  // ../../packages/db/src/schema/device.ts
3850
- init_esm_shims();
3851
3262
  var deviceTable = pgTable(
3852
3263
  "device",
3853
3264
  {
@@ -3864,7 +3275,6 @@ var deviceTable = pgTable(
3864
3275
  );
3865
3276
 
3866
3277
  // ../../packages/db/src/schema/model-price.ts
3867
- init_esm_shims();
3868
3278
  var modelPriceTable = pgTable(
3869
3279
  "model_price",
3870
3280
  {
@@ -3882,7 +3292,6 @@ var modelPriceTable = pgTable(
3882
3292
  );
3883
3293
 
3884
3294
  // ../../packages/db/src/schema/session.ts
3885
- init_esm_shims();
3886
3295
  var sessionTable = pgTable("session", {
3887
3296
  id: uuid("id").primaryKey().default(sql`uuidv7()`),
3888
3297
  userId: uuid("user_id").notNull().references(() => userTable.id, { onDelete: "cascade" }),
@@ -3891,7 +3300,6 @@ var sessionTable = pgTable("session", {
3891
3300
  });
3892
3301
 
3893
3302
  // ../../packages/db/src/schema/usage-hour.ts
3894
- init_esm_shims();
3895
3303
  var usageHourTable = pgTable(
3896
3304
  "usage_hour",
3897
3305
  {
@@ -3917,7 +3325,6 @@ var usageHourTable = pgTable(
3917
3325
  );
3918
3326
 
3919
3327
  // ../../packages/db/src/schema/usage-session.ts
3920
- init_esm_shims();
3921
3328
  var usageSessionTable = pgTable(
3922
3329
  "usage_session",
3923
3330
  {
@@ -3939,52 +3346,14 @@ var usageSessionTable = pgTable(
3939
3346
  })
3940
3347
  );
3941
3348
 
3942
- // ../../packages/api/src/services/session-auth.ts
3943
- import { Context, Effect as Effect2, Layer } from "effect";
3349
+ // ../../packages/api/src/services/auth.ts
3350
+ import { Context as Context2, Effect as Effect4, Layer as Layer2 } from "effect";
3944
3351
 
3945
- // ../../packages/api/src/errors.ts
3946
- init_esm_shims();
3947
- import { Schema as Schema2 } from "effect";
3948
- var ErrorFields = {
3949
- message: Schema2.String
3950
- };
3951
- var UnauthorizedError = class extends Schema2.TaggedErrorClass()("UnauthorizedError", ErrorFields) {
3952
- };
3953
- var ForbiddenError = class extends Schema2.TaggedErrorClass()("ForbiddenError", ErrorFields) {
3954
- };
3955
- var NotFoundError = class extends Schema2.TaggedErrorClass()("NotFoundError", ErrorFields) {
3956
- };
3957
- var ConflictError = class extends Schema2.TaggedErrorClass()("ConflictError", ErrorFields) {
3958
- };
3959
- var ValidationError = class extends Schema2.TaggedErrorClass()("ValidationError", ErrorFields) {
3960
- };
3961
- var RateLimitedError = class extends Schema2.TaggedErrorClass()("RateLimitedError", ErrorFields) {
3962
- };
3963
- var ExternalHttpError = class extends Schema2.TaggedErrorClass()("ExternalHttpError", ErrorFields) {
3964
- };
3965
- var DatabaseError = class extends Schema2.TaggedErrorClass()("DatabaseError", ErrorFields) {
3966
- };
3967
- var AppConfigError = class extends Schema2.TaggedErrorClass()("AppConfigError", ErrorFields) {
3968
- };
3969
- var PricingRefreshError = class extends Schema2.TaggedErrorClass()(
3970
- "PricingRefreshError",
3971
- ErrorFields
3972
- ) {
3973
- };
3974
- var ParserSourceError = class extends Schema2.TaggedErrorClass()("ParserSourceError", ErrorFields) {
3975
- };
3976
- var SyncQuotaExceededError = class extends Schema2.TaggedErrorClass()(
3977
- "SyncQuotaExceededError",
3978
- ErrorFields
3979
- ) {
3980
- };
3981
- var SyncTimestampRejectedError = class extends Schema2.TaggedErrorClass()(
3982
- "SyncTimestampRejectedError",
3983
- ErrorFields
3984
- ) {
3985
- };
3352
+ // ../../packages/api/src/auth/sessions.ts
3353
+ import { Effect as Effect3 } from "effect";
3986
3354
 
3987
3355
  // ../../packages/api/src/services/session-auth.ts
3356
+ import { Context, Effect as Effect2, Layer } from "effect";
3988
3357
  var SESSION_TTL_DAYS = 30;
3989
3358
  var HOURS_PER_DAY = 24;
3990
3359
  var MINUTES_PER_HOUR = 60;
@@ -4040,133 +3409,7 @@ async function deleteSession(db, sessionId) {
4040
3409
  );
4041
3410
  }
4042
3411
 
4043
- // ../../packages/api/src/auth/tokens.ts
4044
- init_esm_shims();
4045
- var import_argon22 = __toESM(require_argon2(), 1);
4046
- import { randomBytes } from "crypto";
4047
- var ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
4048
- var BRAND_PREFIX = "oopst_";
4049
- var BODY_LENGTH = 32;
4050
- var PREFIX_LENGTH = 6;
4051
- var MEMORY_COST2 = 65536;
4052
- var HASH_OPTIONS = {
4053
- type: import_argon22.default.argon2id,
4054
- memoryCost: MEMORY_COST2,
4055
- timeCost: 3,
4056
- parallelism: 1
4057
- };
4058
- function randomBase62(length) {
4059
- const bytes = randomBytes(length);
4060
- let out = "";
4061
- for (let i = 0; i < length; i += 1) {
4062
- out += ALPHABET[bytes[i] % ALPHABET.length] ?? "";
4063
- }
4064
- return out;
4065
- }
4066
- function generateToken() {
4067
- const body = randomBase62(BODY_LENGTH);
4068
- const token = `${BRAND_PREFIX}${body}`;
4069
- const prefix = body.slice(0, PREFIX_LENGTH);
4070
- return {
4071
- token,
4072
- prefix,
4073
- hash: import_argon22.default.hash(token, HASH_OPTIONS)
4074
- };
4075
- }
4076
- async function verifyToken(plain, hash) {
4077
- try {
4078
- return await import_argon22.default.verify(hash, plain);
4079
- } catch {
4080
- return false;
4081
- }
4082
- }
4083
- function extractPrefix(token) {
4084
- if (!token.startsWith(BRAND_PREFIX)) {
4085
- return null;
4086
- }
4087
- const body = token.slice(BRAND_PREFIX.length);
4088
- if (body.length !== BODY_LENGTH) {
4089
- return null;
4090
- }
4091
- return body.slice(0, PREFIX_LENGTH);
4092
- }
4093
-
4094
- // ../../packages/api/src/queries/cost.ts
4095
- init_esm_shims();
4096
- var costExpr = sql`
4097
- coalesce(
4098
- (
4099
- case
4100
- when mp.provider = 'openai' then greatest(uh.input_tokens::numeric - uh.cache_read_tokens::numeric, 0)
4101
- else uh.input_tokens::numeric
4102
- end
4103
- ) * mp.input_per_million / 1000000,
4104
- 0
4105
- )
4106
- + coalesce(uh.output_tokens::numeric * mp.output_per_million / 1000000, 0)
4107
- + coalesce(uh.cache_read_tokens::numeric * mp.cache_read_per_million / 1000000, 0)
4108
- + coalesce(uh.cache_create_tokens::numeric * mp.cache_write_per_million / 1000000, 0)
4109
- `;
4110
- function priceProviderExpr(harnessExpr = sql`uh.harness`, modelExpr = sql`uh.model`) {
4111
- return sql`case
4112
- when ${harnessExpr} = 'codex' then 'openai'
4113
- when ${harnessExpr} = 'claude_code' then 'anthropic'
4114
- when ${harnessExpr} in ('pi', 'hermes', 'opencode')
4115
- and position('/' in ${modelExpr}) > 0
4116
- and split_part(${modelExpr}, '/', 1) = 'openai-codex'
4117
- then 'openai'
4118
- when ${harnessExpr} in ('pi', 'hermes', 'opencode') and position('/' in ${modelExpr}) > 0
4119
- then split_part(${modelExpr}, '/', 1)
4120
- end`;
4121
- }
4122
- function priceModelExpr(harnessExpr = sql`uh.harness`, modelExpr = sql`uh.model`) {
4123
- return sql`case
4124
- when ${harnessExpr} in ('pi', 'hermes', 'opencode') and position('/' in ${modelExpr}) > 0
4125
- then substring(${modelExpr} from position('/' in ${modelExpr}) + 1)
4126
- else ${modelExpr}
4127
- end`;
4128
- }
4129
- function canonicalModelExpr(harnessExpr = sql`uh.harness`, modelExpr = sql`uh.model`) {
4130
- return sql`case
4131
- when ${harnessExpr} in ('pi', 'hermes', 'opencode')
4132
- and position('/' in ${modelExpr}) > 0
4133
- and ${priceProviderExpr(harnessExpr, modelExpr)} = 'openai'
4134
- then ${priceModelExpr(harnessExpr, modelExpr)}
4135
- when ${harnessExpr} in ('pi', 'hermes', 'opencode') and position('/' in ${modelExpr}) > 0
4136
- then ${priceProviderExpr(harnessExpr, modelExpr)} || '/' || ${priceModelExpr(harnessExpr, modelExpr)}
4137
- else ${modelExpr}
4138
- end`;
4139
- }
4140
- var priceJoinCondition = sql`
4141
- mp.provider = ${priceProviderExpr()}
4142
- and mp.model = ${priceModelExpr()}
4143
- `;
4144
-
4145
- // ../../packages/api/src/rpc/auth.ts
4146
- init_esm_shims();
4147
- import { Context as Context3, Effect as Effect5, Layer as Layer3, Schema as Schema4 } from "effect";
4148
- import { Rpc, RpcGroup } from "effect/unstable/rpc";
4149
-
4150
- // ../../packages/api/src/schemas/auth.ts
4151
- init_esm_shims();
4152
- import { Schema as Schema3, SchemaGetter } from "effect";
4153
- var MAX_DISPLAY_NAME_LENGTH = 80;
4154
- var displayNameInput = Schema3.String.check(Schema3.isMaxLength(MAX_DISPLAY_NAME_LENGTH)).pipe(
4155
- Schema3.decodeTo(Schema3.NullOr(Schema3.String), {
4156
- decode: SchemaGetter.transform((value) => {
4157
- const trimmed = value.trim();
4158
- return trimmed.length === 0 ? null : trimmed;
4159
- }),
4160
- encode: SchemaGetter.transform((value) => value ?? "")
4161
- })
4162
- );
4163
- var updateProfileInput = Schema3.Struct({
4164
- displayName: displayNameInput
4165
- });
4166
-
4167
3412
  // ../../packages/api/src/services/auth.ts
4168
- init_esm_shims();
4169
- import { Context as Context2, Effect as Effect4, Layer as Layer2 } from "effect";
4170
3413
  var AuthService = class extends Context2.Service()("@oopst/api/AuthService") {
4171
3414
  };
4172
3415
  var databaseError2 = (err) => new DatabaseError({ message: err instanceof Error ? err.message : "Auth database operation failed" });
@@ -4276,16 +3519,13 @@ var AuthRpcHandlers = AuthRpcs.toLayer({
4276
3519
  }).pipe(Layer3.provide(AuthServiceLive));
4277
3520
 
4278
3521
  // ../../packages/api/src/rpc/devices.ts
4279
- init_esm_shims();
4280
3522
  import { Schema as Schema7 } from "effect";
4281
3523
  import { Rpc as Rpc2, RpcGroup as RpcGroup2 } from "effect/unstable/rpc";
4282
3524
 
4283
3525
  // ../../packages/api/src/schemas/devices.ts
4284
- init_esm_shims();
4285
3526
  import { Schema as Schema6 } from "effect";
4286
3527
 
4287
3528
  // ../../packages/api/src/schemas/common.ts
4288
- init_esm_shims();
4289
3529
  import { Schema as Schema5 } from "effect";
4290
3530
  var ISO_UTC_PATTERN = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/u;
4291
3531
  var CIVIL_DATE_PATTERN = /^\d{4}-\d{2}-\d{2}$/u;
@@ -4388,16 +3628,11 @@ var DevicesRpcs = RpcGroup2.make(
4388
3628
  })
4389
3629
  );
4390
3630
 
4391
- // ../../packages/api/src/rpc/groups.ts
4392
- init_esm_shims();
4393
-
4394
3631
  // ../../packages/api/src/rpc/stats.ts
4395
- init_esm_shims();
4396
3632
  import { Schema as Schema9 } from "effect";
4397
3633
  import { Rpc as Rpc3, RpcGroup as RpcGroup3 } from "effect/unstable/rpc";
4398
3634
 
4399
3635
  // ../../packages/api/src/schemas/stats.ts
4400
- init_esm_shims();
4401
3636
  import { Effect as Effect6, Schema as Schema8 } from "effect";
4402
3637
  var scopeEnum = Schema8.Literals(["all", "me"]);
4403
3638
  var costStackByValueEnum = Schema8.Literals(["device", "harness", "model"]);
@@ -4634,12 +3869,10 @@ var StatsRpcs = RpcGroup3.make(
4634
3869
  );
4635
3870
 
4636
3871
  // ../../packages/api/src/rpc/tokens.ts
4637
- init_esm_shims();
4638
3872
  import { Schema as Schema11 } from "effect";
4639
3873
  import { Rpc as Rpc4, RpcGroup as RpcGroup4 } from "effect/unstable/rpc";
4640
3874
 
4641
3875
  // ../../packages/api/src/schemas/tokens.ts
4642
- init_esm_shims();
4643
3876
  import { Schema as Schema10 } from "effect";
4644
3877
  var MIN_TOKEN_NAME_LENGTH = 1;
4645
3878
  var MAX_TOKEN_NAME_LENGTH = 80;
@@ -4692,12 +3925,10 @@ var TokensRpcs = RpcGroup4.make(
4692
3925
  var WebRpcs = AuthRpcs.merge(StatsRpcs).merge(TokensRpcs).merge(DevicesRpcs);
4693
3926
 
4694
3927
  // ../../packages/api/src/rpc/sync.ts
4695
- init_esm_shims();
4696
3928
  import { Schema as Schema13 } from "effect";
4697
3929
  import { Rpc as Rpc5, RpcGroup as RpcGroup5 } from "effect/unstable/rpc";
4698
3930
 
4699
3931
  // ../../packages/api/src/schemas/sync.ts
4700
- init_esm_shims();
4701
3932
  import { Effect as Effect7, Schema as Schema12 } from "effect";
4702
3933
  var MIN_DEVICE_NAME_LENGTH2 = 1;
4703
3934
  var MAX_DEVICE_NAME_LENGTH2 = 80;
@@ -4709,24 +3940,6 @@ var MAX_BUCKETS_PER_SYNC = 5e3;
4709
3940
  var MAX_SESSIONS_PER_SYNC = 5e3;
4710
3941
  var MAX_BUCKET_SESSION_COUNT = 1e3;
4711
3942
  var MAX_BUCKET_TOKEN_COUNT = null;
4712
- var MAX_TOKENS_PER_SYNC = null;
4713
- var MAX_DEVICE_DAY_TOKENS = null;
4714
- var MAX_DEVICE_DAY_SESSIONS = 1e3;
4715
- var MAX_TIMESTAMP_PAST_DAYS = 3650;
4716
- var MAX_TIMESTAMP_FUTURE_HOURS = 6;
4717
- var MAX_SESSION_DURATION_DAYS = null;
4718
- var syncUploadLimits = {
4719
- maxBucketsPerSync: MAX_BUCKETS_PER_SYNC,
4720
- maxSessionsPerSync: MAX_SESSIONS_PER_SYNC,
4721
- maxBucketTokenCount: MAX_BUCKET_TOKEN_COUNT,
4722
- maxBucketSessionCount: MAX_BUCKET_SESSION_COUNT,
4723
- maxTokensPerSync: MAX_TOKENS_PER_SYNC,
4724
- maxDeviceDayTokens: MAX_DEVICE_DAY_TOKENS,
4725
- maxDeviceDaySessions: MAX_DEVICE_DAY_SESSIONS,
4726
- maxTimestampPastDays: MAX_TIMESTAMP_PAST_DAYS,
4727
- maxTimestampFutureHours: MAX_TIMESTAMP_FUTURE_HOURS,
4728
- maxSessionDurationDays: MAX_SESSION_DURATION_DAYS
4729
- };
4730
3943
  var HARNESSES = ["codex", "claude_code", "pi", "hermes", "opencode"];
4731
3944
  var harnessEnum = Schema12.Literals(HARNESSES);
4732
3945
  var deviceNameSchema2 = Schema12.String.check(
@@ -4740,11 +3953,11 @@ var getWatermarkOutput = Schema12.Struct({
4740
3953
  watermarkHourUtc: Schema12.NullOr(isoUtcString),
4741
3954
  sessionKeySalt: hex64.check(Schema12.isLengthBetween(SESSION_KEY_SALT_LENGTH, SESSION_KEY_SALT_LENGTH))
4742
3955
  });
4743
- function boundedInteger(max2) {
4744
- if (max2 === null) {
3956
+ function boundedInteger(max) {
3957
+ if (max === null) {
4745
3958
  return nonNegativeSafeInteger;
4746
3959
  }
4747
- return nonNegativeSafeInteger.check(Schema12.isLessThanOrEqualTo(max2));
3960
+ return nonNegativeSafeInteger.check(Schema12.isLessThanOrEqualTo(max));
4748
3961
  }
4749
3962
  var bucketInput = Schema12.Struct({
4750
3963
  harness: harnessEnum,
@@ -4786,1076 +3999,8 @@ var SyncRpcs = RpcGroup5.make(
4786
3999
  })
4787
4000
  );
4788
4001
 
4789
- // ../../packages/api/src/rpc/system.ts
4790
- init_esm_shims();
4791
- import { Effect as Effect8, Schema as Schema14 } from "effect";
4792
- import { Rpc as Rpc6, RpcGroup as RpcGroup6 } from "effect/unstable/rpc";
4793
- var SystemPingResponse = Schema14.Struct({
4794
- ok: Schema14.Boolean
4795
- });
4796
- var SystemRpcs = RpcGroup6.make(
4797
- Rpc6.make("system.ping", {
4798
- success: SystemPingResponse
4799
- })
4800
- );
4801
- var SystemRpcHandlers = SystemRpcs.toLayer({
4802
- "system.ping": () => Effect8.succeed({ ok: true })
4803
- });
4804
-
4805
- // ../../packages/api/src/services/devices.ts
4806
- init_esm_shims();
4807
- import { Context as Context4, Effect as Effect9, Layer as Layer4 } from "effect";
4808
- var DUPLICATE_DEVICE_NAME_MESSAGE = "A device with this name already exists";
4809
- var DEVICE_NOT_FOUND_MESSAGE = "Device not found";
4810
- var PG_UNIQUE_VIOLATION = "23505";
4811
- var DeviceService = class extends Context4.Service()("@oopst/api/DeviceService") {
4812
- };
4813
- function isUniqueViolation(err) {
4814
- return typeof err === "object" && err !== null && "code" in err && err.code === PG_UNIQUE_VIOLATION;
4815
- }
4816
- var duplicateDeviceNameError = () => new ConflictError({ message: DUPLICATE_DEVICE_NAME_MESSAGE });
4817
- var deviceNotFoundError = () => new NotFoundError({ message: DEVICE_NOT_FOUND_MESSAGE });
4818
- var databaseError3 = (err) => new DatabaseError({ message: err instanceof Error ? err.message : "Device database operation failed" });
4819
- var makeDeviceService = () => ({
4820
- rename: (input) => Effect9.gen(function* () {
4821
- const duplicate = yield* Effect9.tryPromise({
4822
- try: async () => {
4823
- const [row2] = await input.db.select({ id: deviceTable.id }).from(deviceTable).where(
4824
- and(eq(deviceTable.userId, input.userId), eq(deviceTable.name, input.name), ne(deviceTable.id, input.id))
4825
- ).limit(1);
4826
- return row2;
4827
- },
4828
- catch: databaseError3
4829
- });
4830
- if (duplicate) {
4831
- return yield* Effect9.fail(duplicateDeviceNameError());
4832
- }
4833
- const row = yield* Effect9.tryPromise({
4834
- try: async () => {
4835
- const [updated] = await input.db.update(deviceTable).set({ name: input.name }).where(and(eq(deviceTable.id, input.id), eq(deviceTable.userId, input.userId))).returning({
4836
- id: deviceTable.id,
4837
- name: deviceTable.name,
4838
- lastSeen: deviceTable.lastSeen
4839
- });
4840
- return updated;
4841
- },
4842
- catch: (err) => isUniqueViolation(err) ? duplicateDeviceNameError() : databaseError3(err)
4843
- });
4844
- if (!row) {
4845
- return yield* Effect9.fail(deviceNotFoundError());
4846
- }
4847
- return {
4848
- id: row.id,
4849
- name: row.name,
4850
- lastSeen: row.lastSeen.toISOString()
4851
- };
4852
- })
4853
- });
4854
- var DeviceServiceLive = Layer4.succeed(DeviceService, makeDeviceService());
4855
-
4856
- // ../../packages/api/src/services/stats.ts
4857
- init_esm_shims();
4858
- import { Context as Context5, Effect as Effect10, Layer as Layer5 } from "effect";
4859
-
4860
- // ../../packages/api/src/queries/missing-prices.ts
4861
- init_esm_shims();
4862
- var seen = /* @__PURE__ */ new Set();
4863
- async function logMissingPrices(db, logger) {
4864
- try {
4865
- const { rows } = await db.execute(sql`
4866
- select distinct uh.harness, uh.model
4867
- from usage_hour uh
4868
- left join model_price mp
4869
- on ${priceJoinCondition}
4870
- where uh.hour_utc >= now() - interval '90 days'
4871
- and mp.model is null
4872
- `);
4873
- for (const row of rows) {
4874
- const key6 = `${row.harness}:${row.model}`;
4875
- if (seen.has(key6)) {
4876
- continue;
4877
- }
4878
- seen.add(key6);
4879
- try {
4880
- logger.warn({ harness: row.harness, model: row.model }, "missing price");
4881
- } catch {
4882
- }
4883
- }
4884
- } catch {
4885
- }
4886
- }
4887
-
4888
- // ../../packages/api/src/services/stats.ts
4889
- var StatsService = class extends Context5.Service()("@oopst/api/StatsService") {
4890
- };
4891
- var noopLogger = { warn: () => void 0 };
4892
- var databaseError4 = (err) => new DatabaseError({ message: err instanceof Error ? err.message : "Stats database operation failed" });
4893
- var usageTokensExpr = sql`
4894
- uh.input_tokens
4895
- + uh.output_tokens
4896
- + uh.cache_read_tokens
4897
- + uh.cache_create_tokens
4898
- `;
4899
- function timestampRangeClause(input, timestampExpr) {
4900
- if (input.startDate && input.endDate) {
4901
- return sql`(${timestampExpr} at time zone ${input.timeZone})::date between ${input.startDate}::date and ${input.endDate}::date`;
4902
- }
4903
- return sql`${timestampExpr} >= now() - (${input.days} || ' days')::interval`;
4904
- }
4905
- function toIsoString(value) {
4906
- if (!value) {
4907
- return null;
4908
- }
4909
- return (value instanceof Date ? value : new Date(value)).toISOString();
4910
- }
4911
- function harnessSeriesExpr(harnessExpr = sql`uh.harness`) {
4912
- return sql`case ${harnessExpr}
4913
- when 'codex' then 'Codex'
4914
- when 'claude_code' then 'Claude Code'
4915
- when 'pi' then 'Pi'
4916
- when 'hermes' then 'Hermes'
4917
- when 'opencode' then 'OpenCode'
4918
- else ${harnessExpr}
4919
- end`;
4920
- }
4921
- function localDayExpr(timeZone, timestampExpr = sql`uh.hour_utc`) {
4922
- return sql`to_char(date_trunc('day', ${timestampExpr} at time zone ${timeZone}), 'YYYY-MM-DD')`;
4923
- }
4924
- function localIsoWeekdayExpr(timeZone, timestampExpr = sql`uh.hour_utc`) {
4925
- return sql`extract(isodow from (${timestampExpr} at time zone ${timeZone}))::int`;
4926
- }
4927
- function localHourExpr(timeZone, timestampExpr = sql`uh.hour_utc`) {
4928
- return sql`extract(hour from (${timestampExpr} at time zone ${timeZone}))::int`;
4929
- }
4930
- function stackByForScope(scope, stackBy) {
4931
- if (scope === "all" && stackBy === "device") {
4932
- return void 0;
4933
- }
4934
- return stackBy;
4935
- }
4936
- function toTopDimensionRow(row) {
4937
- return {
4938
- rank: row.rank,
4939
- name: row.name,
4940
- usd: row.usd,
4941
- tokens: row.tokens,
4942
- sessions: row.sessions
4943
- };
4944
- }
4945
- async function selectSessionDistribution(command, bucketExpr) {
4946
- const stackBy = stackByForScope(command.input.scope, command.input.stackBy);
4947
- const rangeClause = timestampRangeClause(command.input, sql`us.started_at`);
4948
- const meClause = command.input.scope === "me" ? sql`and us.user_id = ${command.userId}` : sql``;
4949
- let result;
4950
- if (stackBy === "device") {
4951
- result = await command.db.execute(sql`
4952
- select
4953
- ${bucketExpr} as bucket,
4954
- d.name as "seriesName",
4955
- count(*)::int as sessions
4956
- from usage_session us
4957
- join device d on d.id = us.device_id
4958
- where ${rangeClause}
4959
- ${meClause}
4960
- group by 1, d.name
4961
- order by 1 asc, d.name asc
4962
- `);
4963
- } else if (stackBy === "harness") {
4964
- result = await command.db.execute(sql`
4965
- select
4966
- ${bucketExpr} as bucket,
4967
- ${harnessSeriesExpr(sql`us.harness`)} as "seriesName",
4968
- count(*)::int as sessions
4969
- from usage_session us
4970
- where ${rangeClause}
4971
- ${meClause}
4972
- group by 1, us.harness
4973
- order by 1 asc, us.harness asc
4974
- `);
4975
- } else {
4976
- result = await command.db.execute(sql`
4977
- select
4978
- ${bucketExpr} as bucket,
4979
- null::text as "seriesName",
4980
- count(*)::int as sessions
4981
- from usage_session us
4982
- where ${rangeClause}
4983
- ${meClause}
4984
- group by 1
4985
- order by 1 asc
4986
- `);
4987
- }
4988
- return result.rows;
4989
- }
4990
- var makeStatsService = () => ({
4991
- dailyCost: (command) => Effect10.tryPromise({
4992
- try: async () => {
4993
- const stackBy = stackByForScope(command.input.scope, command.input.stackBy);
4994
- const rangeClause = timestampRangeClause(command.input, sql`uh.hour_utc`);
4995
- const meClause = command.input.scope === "me" ? sql`and uh.user_id = ${command.userId}` : sql``;
4996
- const dateExpr = localDayExpr(command.input.timeZone);
4997
- let result;
4998
- if (stackBy === "device") {
4999
- result = await command.db.execute(sql`
5000
- select
5001
- ${dateExpr} as date,
5002
- d.name as "seriesName",
5003
- coalesce(sum(${costExpr}), 0)::float as usd
5004
- from usage_hour uh
5005
- join device d on d.id = uh.device_id
5006
- left join model_price mp
5007
- on ${priceJoinCondition}
5008
- where ${rangeClause}
5009
- ${meClause}
5010
- group by 1, d.name
5011
- order by 1 asc, d.name asc
5012
- `);
5013
- } else if (stackBy === "harness") {
5014
- result = await command.db.execute(sql`
5015
- select
5016
- ${dateExpr} as date,
5017
- ${harnessSeriesExpr()} as "seriesName",
5018
- coalesce(sum(${costExpr}), 0)::float as usd
5019
- from usage_hour uh
5020
- left join model_price mp
5021
- on ${priceJoinCondition}
5022
- where ${rangeClause}
5023
- ${meClause}
5024
- group by 1, uh.harness
5025
- order by 1 asc, uh.harness asc
5026
- `);
5027
- } else if (stackBy === "model") {
5028
- const modelNameExpr = canonicalModelExpr();
5029
- result = await command.db.execute(sql`
5030
- select
5031
- ${dateExpr} as date,
5032
- ${modelNameExpr} as "seriesName",
5033
- coalesce(sum(${costExpr}), 0)::float as usd
5034
- from usage_hour uh
5035
- left join model_price mp
5036
- on ${priceJoinCondition}
5037
- where ${rangeClause}
5038
- ${meClause}
5039
- group by 1, 2
5040
- order by 1 asc, 2 asc
5041
- `);
5042
- } else {
5043
- result = await command.db.execute(sql`
5044
- select
5045
- ${dateExpr} as date,
5046
- null::text as "seriesName",
5047
- coalesce(sum(${costExpr}), 0)::float as usd
5048
- from usage_hour uh
5049
- left join model_price mp
5050
- on ${priceJoinCondition}
5051
- where ${rangeClause}
5052
- ${meClause}
5053
- group by 1
5054
- order by 1 asc
5055
- `);
5056
- }
5057
- return result.rows.map((row) => ({
5058
- date: row.date,
5059
- seriesName: row.seriesName,
5060
- usd: row.usd
5061
- }));
5062
- },
5063
- catch: databaseError4
5064
- }),
5065
- dailySessions: (command) => Effect10.tryPromise({
5066
- try: async () => {
5067
- const stackBy = stackByForScope(command.input.scope, command.input.stackBy);
5068
- const rangeClause = timestampRangeClause(command.input, sql`us.started_at`);
5069
- const meClause = command.input.scope === "me" ? sql`and us.user_id = ${command.userId}` : sql``;
5070
- const dateExpr = localDayExpr(command.input.timeZone, sql`us.started_at`);
5071
- let result;
5072
- if (stackBy === "device") {
5073
- result = await command.db.execute(sql`
5074
- select
5075
- ${dateExpr} as date,
5076
- d.name as "seriesName",
5077
- count(*)::int as sessions
5078
- from usage_session us
5079
- join device d on d.id = us.device_id
5080
- where ${rangeClause}
5081
- ${meClause}
5082
- group by 1, d.name
5083
- order by 1 asc, d.name asc
5084
- `);
5085
- } else if (stackBy === "harness") {
5086
- result = await command.db.execute(sql`
5087
- select
5088
- ${dateExpr} as date,
5089
- ${harnessSeriesExpr(sql`us.harness`)} as "seriesName",
5090
- count(*)::int as sessions
5091
- from usage_session us
5092
- where ${rangeClause}
5093
- ${meClause}
5094
- group by 1, us.harness
5095
- order by 1 asc, us.harness asc
5096
- `);
5097
- } else {
5098
- result = await command.db.execute(sql`
5099
- select
5100
- ${dateExpr} as date,
5101
- null::text as "seriesName",
5102
- count(*)::int as sessions
5103
- from usage_session us
5104
- where ${rangeClause}
5105
- ${meClause}
5106
- group by 1
5107
- order by 1 asc
5108
- `);
5109
- }
5110
- return result.rows.map((row) => ({
5111
- date: row.date,
5112
- seriesName: row.seriesName,
5113
- sessions: row.sessions
5114
- }));
5115
- },
5116
- catch: databaseError4
5117
- }),
5118
- devices: (command) => Effect10.tryPromise({
5119
- try: async () => {
5120
- const rows = await command.db.select({
5121
- id: deviceTable.id,
5122
- name: deviceTable.name,
5123
- lastSeen: deviceTable.lastSeen
5124
- }).from(deviceTable).where(eq(deviceTable.userId, command.userId)).orderBy(desc(deviceTable.lastSeen));
5125
- return rows.map((row) => ({
5126
- id: row.id,
5127
- name: row.name,
5128
- lastSeen: row.lastSeen.toISOString()
5129
- }));
5130
- },
5131
- catch: databaseError4
5132
- }),
5133
- hourlySessions: (command) => Effect10.tryPromise({
5134
- try: async () => {
5135
- const rows = await selectSessionDistribution(
5136
- command,
5137
- localHourExpr(command.input.timeZone, sql`us.started_at`)
5138
- );
5139
- return rows.map((row) => ({
5140
- hour: row.bucket,
5141
- seriesName: row.seriesName,
5142
- sessions: row.sessions
5143
- }));
5144
- },
5145
- catch: databaseError4
5146
- }),
5147
- leaderboard: (command) => Effect10.tryPromise({
5148
- try: async () => {
5149
- const usageRangeClause = timestampRangeClause(command.input, sql`uh.hour_utc`);
5150
- const sessionRangeClause = timestampRangeClause(command.input, sql`us.started_at`);
5151
- const result = await command.db.execute(sql`
5152
- with cost_by_user as (
5153
- select
5154
- uh.user_id,
5155
- coalesce(sum(${costExpr}), 0)::float as usd,
5156
- coalesce(sum(
5157
- uh.input_tokens
5158
- + uh.output_tokens
5159
- + uh.cache_read_tokens
5160
- + uh.cache_create_tokens
5161
- ), 0)::float as tokens
5162
- from usage_hour uh
5163
- left join model_price mp
5164
- on ${priceJoinCondition}
5165
- where ${usageRangeClause}
5166
- group by uh.user_id
5167
- ),
5168
- sessions_by_user as (
5169
- select
5170
- us.user_id,
5171
- count(*)::int as sessions
5172
- from usage_session us
5173
- where ${sessionRangeClause}
5174
- group by us.user_id
5175
- ),
5176
- leaderboard as (
5177
- select
5178
- u.id as "userId",
5179
- coalesce(nullif(u.display_name, ''), u.email) as "userLabel",
5180
- coalesce(c.usd, 0)::float as usd,
5181
- coalesce(c.tokens, 0)::float as tokens,
5182
- coalesce(s.sessions, 0)::int as sessions
5183
- from "user" u
5184
- left join cost_by_user c on c.user_id = u.id
5185
- left join sessions_by_user s on s.user_id = u.id
5186
- where c.user_id is not null
5187
- or s.user_id is not null
5188
- )
5189
- select
5190
- row_number() over (
5191
- order by usd desc, tokens desc, sessions desc, "userLabel" asc
5192
- )::int as rank,
5193
- "userId",
5194
- "userLabel",
5195
- usd,
5196
- tokens,
5197
- sessions
5198
- from leaderboard
5199
- order by rank asc
5200
- limit ${command.input.limit}
5201
- `);
5202
- return result.rows.map((row) => ({
5203
- rank: row.rank,
5204
- userId: row.userId,
5205
- userLabel: row.userLabel,
5206
- usd: row.usd,
5207
- tokens: row.tokens,
5208
- sessions: row.sessions
5209
- }));
5210
- },
5211
- catch: databaseError4
5212
- }),
5213
- participants: (command) => Effect10.tryPromise({
5214
- try: async () => {
5215
- const result = await command.db.execute(sql`
5216
- select
5217
- u.id as "userId",
5218
- coalesce(nullif(u.display_name, ''), u.email) as "userLabel",
5219
- max(d.last_seen) as "latestSyncAt"
5220
- from ${userTable} u
5221
- left join ${deviceTable} d on d.user_id = u.id
5222
- group by u.id, u.display_name, u.email
5223
- order by max(d.last_seen) desc nulls last, "userLabel" asc
5224
- `);
5225
- return result.rows.map((row) => ({
5226
- userId: row.userId,
5227
- userLabel: row.userLabel,
5228
- latestSyncAt: toIsoString(row.latestSyncAt)
5229
- }));
5230
- },
5231
- catch: databaseError4
5232
- }),
5233
- summary: (command) => Effect10.tryPromise({
5234
- try: async () => {
5235
- const meClause = command.input.scope === "me" ? sql`and uh.user_id = ${command.userId}` : sql``;
5236
- const subjectExpr = command.input.scope === "me" ? sql`uh.device_id` : sql`uh.user_id`;
5237
- const rangeClause = timestampRangeClause(command.input, sql`uh.hour_utc`);
5238
- const costResult = await command.db.execute(sql`
5239
- select
5240
- coalesce(sum(${costExpr}) filter (where ${rangeClause}), 0)::float as "rangeUsd",
5241
- (count(distinct ${subjectExpr}) filter (where ${rangeClause}))::int as "rangeSubjectCount",
5242
- coalesce(sum(${costExpr}), 0)::float as "totalUsd"
5243
- from usage_hour uh
5244
- left join model_price mp
5245
- on ${priceJoinCondition}
5246
- where true
5247
- ${meClause}
5248
- `);
5249
- const sessionMeClause = command.input.scope === "me" ? sql`and us.user_id = ${command.userId}` : sql``;
5250
- const sessionRangeClause = timestampRangeClause(command.input, sql`us.started_at`);
5251
- const sessionResult = await command.db.execute(sql`
5252
- select
5253
- (count(*) filter (where ${sessionRangeClause}))::int as "rangeSessions",
5254
- count(*)::int as "totalSessions"
5255
- from usage_session us
5256
- where true
5257
- ${sessionMeClause}
5258
- `);
5259
- const [row] = costResult.rows;
5260
- const [sessionRow] = sessionResult.rows;
5261
- return {
5262
- rangeUsd: row?.rangeUsd ?? 0,
5263
- rangeSessions: sessionRow?.rangeSessions ?? 0,
5264
- rangeSubjectCount: row?.rangeSubjectCount ?? 0,
5265
- totalUsd: row?.totalUsd ?? 0,
5266
- totalSessions: sessionRow?.totalSessions ?? 0
5267
- };
5268
- },
5269
- catch: databaseError4
5270
- }),
5271
- topDimensions: (command) => Effect10.tryPromise({
5272
- try: async () => {
5273
- const usageRangeClause = timestampRangeClause(command.input, sql`uh.hour_utc`);
5274
- const sessionRangeClause = timestampRangeClause(command.input, sql`us.started_at`);
5275
- const modelNameExpr = canonicalModelExpr();
5276
- const models = await command.db.execute(sql`
5277
- with model_totals as (
5278
- select
5279
- ${modelNameExpr} as name,
5280
- coalesce(sum(${costExpr}), 0)::float as usd,
5281
- coalesce(sum(
5282
- uh.input_tokens
5283
- + uh.output_tokens
5284
- + uh.cache_read_tokens
5285
- + uh.cache_create_tokens
5286
- ), 0)::float as tokens
5287
- from usage_hour uh
5288
- left join model_price mp
5289
- on ${priceJoinCondition}
5290
- where ${usageRangeClause}
5291
- group by 1
5292
- )
5293
- select
5294
- row_number() over (order by usd desc, tokens desc, name asc)::int as rank,
5295
- name,
5296
- usd,
5297
- tokens,
5298
- null::int as sessions
5299
- from model_totals
5300
- order by rank asc
5301
- limit ${command.input.limit}
5302
- `);
5303
- const harnesses = await command.db.execute(sql`
5304
- with cost_by_harness as (
5305
- select
5306
- uh.harness,
5307
- ${harnessSeriesExpr()} as name,
5308
- coalesce(sum(${costExpr}), 0)::float as usd,
5309
- coalesce(sum(
5310
- uh.input_tokens
5311
- + uh.output_tokens
5312
- + uh.cache_read_tokens
5313
- + uh.cache_create_tokens
5314
- ), 0)::float as tokens
5315
- from usage_hour uh
5316
- left join model_price mp
5317
- on ${priceJoinCondition}
5318
- where ${usageRangeClause}
5319
- group by uh.harness
5320
- ),
5321
- sessions_by_harness as (
5322
- select
5323
- us.harness,
5324
- count(*)::int as sessions
5325
- from usage_session us
5326
- where ${sessionRangeClause}
5327
- group by us.harness
5328
- ),
5329
- harness_totals as (
5330
- select
5331
- coalesce(c.name, ${harnessSeriesExpr(sql`s.harness`)}) as name,
5332
- coalesce(c.usd, 0)::float as usd,
5333
- coalesce(c.tokens, 0)::float as tokens,
5334
- coalesce(s.sessions, 0)::int as sessions
5335
- from cost_by_harness c
5336
- full outer join sessions_by_harness s on s.harness = c.harness
5337
- )
5338
- select
5339
- row_number() over (order by usd desc, tokens desc, sessions desc, name asc)::int as rank,
5340
- name,
5341
- usd,
5342
- tokens,
5343
- sessions
5344
- from harness_totals
5345
- order by rank asc
5346
- limit ${command.input.limit}
5347
- `);
5348
- logMissingPrices(command.db, noopLogger).catch(() => void 0);
5349
- return {
5350
- harnesses: harnesses.rows.map(toTopDimensionRow),
5351
- models: models.rows.map(toTopDimensionRow)
5352
- };
5353
- },
5354
- catch: databaseError4
5355
- }),
5356
- usageDetails: (command) => Effect10.tryPromise({
5357
- try: async () => {
5358
- const usageRangeClause = timestampRangeClause(command.input, sql`uh.hour_utc`);
5359
- const sessionRangeClause = timestampRangeClause(command.input, sql`us.started_at`);
5360
- let result;
5361
- if (command.input.stackBy === "device") {
5362
- result = await command.db.execute(sql`
5363
- with usage_totals as (
5364
- select
5365
- uh.device_id::text as key,
5366
- d.name as name,
5367
- coalesce(sum(${usageTokensExpr}) filter (where ${usageRangeClause}), 0)::float as tokens,
5368
- coalesce(sum(${costExpr}) filter (where ${usageRangeClause}), 0)::float as usd,
5369
- coalesce(sum(${costExpr}), 0)::float as "totalUsd"
5370
- from usage_hour uh
5371
- join device d on d.id = uh.device_id
5372
- left join model_price mp
5373
- on ${priceJoinCondition}
5374
- where uh.user_id = ${command.userId}
5375
- group by uh.device_id, d.name
5376
- ),
5377
- session_totals as (
5378
- select
5379
- us.device_id::text as key,
5380
- d.name as name,
5381
- count(*)::int as sessions
5382
- from usage_session us
5383
- join device d on d.id = us.device_id
5384
- where us.user_id = ${command.userId}
5385
- and ${sessionRangeClause}
5386
- group by us.device_id, d.name
5387
- )
5388
- select
5389
- coalesce(u.key, s.key) as id,
5390
- coalesce(u.name, s.name) as name,
5391
- coalesce(u.tokens, 0)::float as tokens,
5392
- coalesce(s.sessions, 0)::int as sessions,
5393
- coalesce(u.usd, 0)::float as usd,
5394
- coalesce(u."totalUsd", 0)::float as "totalUsd"
5395
- from usage_totals u
5396
- full outer join session_totals s on s.key = u.key
5397
- where coalesce(u.tokens, 0) > 0
5398
- or coalesce(s.sessions, 0) > 0
5399
- or coalesce(u.usd, 0) > 0
5400
- order by usd desc, tokens desc, sessions desc, name asc
5401
- `);
5402
- } else if (command.input.stackBy === "harness") {
5403
- result = await command.db.execute(sql`
5404
- with usage_totals as (
5405
- select
5406
- uh.harness as key,
5407
- ${harnessSeriesExpr()} as name,
5408
- coalesce(sum(${usageTokensExpr}) filter (where ${usageRangeClause}), 0)::float as tokens,
5409
- coalesce(sum(${costExpr}) filter (where ${usageRangeClause}), 0)::float as usd,
5410
- coalesce(sum(${costExpr}), 0)::float as "totalUsd"
5411
- from usage_hour uh
5412
- left join model_price mp
5413
- on ${priceJoinCondition}
5414
- where uh.user_id = ${command.userId}
5415
- group by uh.harness
5416
- ),
5417
- session_totals as (
5418
- select
5419
- us.harness as key,
5420
- ${harnessSeriesExpr(sql`us.harness`)} as name,
5421
- count(*)::int as sessions
5422
- from usage_session us
5423
- where us.user_id = ${command.userId}
5424
- and ${sessionRangeClause}
5425
- group by us.harness
5426
- )
5427
- select
5428
- coalesce(u.key, s.key) as id,
5429
- coalesce(u.name, s.name) as name,
5430
- coalesce(u.tokens, 0)::float as tokens,
5431
- coalesce(s.sessions, 0)::int as sessions,
5432
- coalesce(u.usd, 0)::float as usd,
5433
- coalesce(u."totalUsd", 0)::float as "totalUsd"
5434
- from usage_totals u
5435
- full outer join session_totals s on s.key = u.key
5436
- where coalesce(u.tokens, 0) > 0
5437
- or coalesce(s.sessions, 0) > 0
5438
- or coalesce(u.usd, 0) > 0
5439
- order by usd desc, tokens desc, sessions desc, name asc
5440
- `);
5441
- } else {
5442
- const modelNameExpr = canonicalModelExpr();
5443
- result = await command.db.execute(sql`
5444
- with usage_totals as (
5445
- select
5446
- ${modelNameExpr} as name,
5447
- coalesce(sum(${usageTokensExpr}) filter (where ${usageRangeClause}), 0)::float as tokens,
5448
- coalesce(sum(${costExpr}) filter (where ${usageRangeClause}), 0)::float as usd,
5449
- coalesce(sum(${costExpr}), 0)::float as "totalUsd"
5450
- from usage_hour uh
5451
- left join model_price mp
5452
- on ${priceJoinCondition}
5453
- where uh.user_id = ${command.userId}
5454
- group by 1
5455
- )
5456
- select
5457
- name as id,
5458
- name,
5459
- tokens,
5460
- null::int as sessions,
5461
- usd,
5462
- "totalUsd"
5463
- from usage_totals
5464
- where tokens > 0
5465
- or usd > 0
5466
- order by usd desc, tokens desc, name asc
5467
- `);
5468
- }
5469
- return result.rows.map((row) => ({
5470
- id: row.id,
5471
- name: row.name,
5472
- tokens: row.tokens,
5473
- sessions: row.sessions,
5474
- usd: row.usd,
5475
- totalUsd: row.totalUsd
5476
- }));
5477
- },
5478
- catch: databaseError4
5479
- }),
5480
- weekdaySessions: (command) => Effect10.tryPromise({
5481
- try: async () => {
5482
- const rows = await selectSessionDistribution(
5483
- command,
5484
- localIsoWeekdayExpr(command.input.timeZone, sql`us.started_at`)
5485
- );
5486
- return rows.map((row) => ({
5487
- weekday: row.bucket,
5488
- seriesName: row.seriesName,
5489
- sessions: row.sessions
5490
- }));
5491
- },
5492
- catch: databaseError4
5493
- })
5494
- });
5495
- var StatsServiceLive = Layer5.succeed(StatsService, makeStatsService());
5496
-
5497
- // ../../packages/api/src/services/sync.ts
5498
- init_esm_shims();
5499
- import { Context as Context6, Effect as Effect11, Layer as Layer6 } from "effect";
5500
- var HOURS_PER_DAY3 = 24;
5501
- var MINUTES_PER_HOUR3 = 60;
5502
- var SECONDS_PER_MINUTE3 = 60;
5503
- var MS_PER_SECOND3 = 1e3;
5504
- var MS_PER_HOUR = MINUTES_PER_HOUR3 * SECONDS_PER_MINUTE3 * MS_PER_SECOND3;
5505
- var MS_PER_DAY2 = HOURS_PER_DAY3 * MS_PER_HOUR;
5506
- var MAX_SYNC_TIMESTAMP_AGE_MS = syncUploadLimits.maxTimestampPastDays * MS_PER_DAY2;
5507
- var MAX_SYNC_FUTURE_SKEW_MS = syncUploadLimits.maxTimestampFutureHours * MS_PER_HOUR;
5508
- var MAX_SESSION_DURATION_MS = syncUploadLimits.maxSessionDurationDays === null ? null : syncUploadLimits.maxSessionDurationDays * MS_PER_DAY2;
5509
- var UTC_DAY_LENGTH = 10;
5510
- var UPSERT_CHUNK_SIZE = 500;
5511
- var SyncService = class extends Context6.Service()("@oopst/api/SyncService") {
5512
- };
5513
- var databaseError5 = (err) => new DatabaseError({ message: err instanceof Error ? err.message : "Sync database operation failed" });
5514
- var syncValidationError = (err) => {
5515
- if (err instanceof SyncQuotaExceededError || err instanceof SyncTimestampRejectedError) {
5516
- return err;
5517
- }
5518
- return new SyncTimestampRejectedError({ message: err instanceof Error ? err.message : "Invalid sync payload" });
5519
- };
5520
- function toIsoString2(value) {
5521
- if (!value) {
5522
- return null;
5523
- }
5524
- return (value instanceof Date ? value : new Date(value)).toISOString();
5525
- }
5526
- function bucketTokenTotal(bucket) {
5527
- return bucket.inputTokens + bucket.outputTokens + bucket.cacheReadTokens + bucket.cacheCreateTokens;
5528
- }
5529
- function parseSyncTimestamp(field, value, nowMs) {
5530
- const date2 = new Date(value);
5531
- const time2 = date2.getTime();
5532
- if (Number.isNaN(time2)) {
5533
- throw new SyncTimestampRejectedError({ message: `${field} must be a valid UTC timestamp` });
5534
- }
5535
- if (time2 < nowMs - MAX_SYNC_TIMESTAMP_AGE_MS || time2 > nowMs + MAX_SYNC_FUTURE_SKEW_MS) {
5536
- throw new SyncTimestampRejectedError({ message: `${field} is outside the allowed sync timestamp window` });
5537
- }
5538
- return date2;
5539
- }
5540
- function assertUtcHour(field, value, nowMs) {
5541
- const date2 = parseSyncTimestamp(field, value, nowMs);
5542
- if (date2.getUTCMinutes() !== 0 || date2.getUTCSeconds() !== 0 || date2.getUTCMilliseconds() !== 0) {
5543
- throw new SyncTimestampRejectedError({ message: `${field} must be aligned to the start of a UTC hour` });
5544
- }
5545
- return date2;
5546
- }
5547
- function assertSessionRange(field, session, nowMs) {
5548
- const startedAt = parseSyncTimestamp(`${field}.startedAt`, session.startedAt, nowMs);
5549
- const lastSeenAt = parseSyncTimestamp(`${field}.lastSeenAt`, session.lastSeenAt, nowMs);
5550
- const durationMs = lastSeenAt.getTime() - startedAt.getTime();
5551
- if (durationMs < 0) {
5552
- throw new SyncTimestampRejectedError({ message: `${field}.lastSeenAt must be greater than or equal to startedAt` });
5553
- }
5554
- if (MAX_SESSION_DURATION_MS !== null && durationMs > MAX_SESSION_DURATION_MS) {
5555
- throw new SyncTimestampRejectedError({ message: `${field} exceeds the maximum session duration` });
5556
- }
5557
- }
5558
- function assertSyncPayload(input) {
5559
- const nowMs = Date.now();
5560
- let uploadTokens = 0;
5561
- for (const [index2, bucket] of input.buckets.entries()) {
5562
- assertUtcHour(`buckets[${index2}].hourUtc`, bucket.hourUtc, nowMs);
5563
- uploadTokens += bucketTokenTotal(bucket);
5564
- }
5565
- if (syncUploadLimits.maxTokensPerSync !== null && uploadTokens > syncUploadLimits.maxTokensPerSync) {
5566
- throw new SyncQuotaExceededError({
5567
- message: `sync upload exceeds the per-token/device upload quota of ${syncUploadLimits.maxTokensPerSync} tokens`
5568
- });
5569
- }
5570
- for (const [index2, session] of input.sessions.entries()) {
5571
- assertSessionRange(`sessions[${index2}]`, session, nowMs);
5572
- }
5573
- }
5574
- function utcDay(value) {
5575
- return new Date(value).toISOString().slice(0, UTC_DAY_LENGTH);
5576
- }
5577
- function unique(values) {
5578
- return Array.from(new Set(values));
5579
- }
5580
- function daySqlList(days) {
5581
- return sql.join(
5582
- days.map((day) => sql`${day}::date`),
5583
- sql`, `
5584
- );
5585
- }
5586
- async function upsertUsageHourChunks(tx, input) {
5587
- for (let i = 0; i < input.buckets.length; i += UPSERT_CHUNK_SIZE) {
5588
- const slice = input.buckets.slice(i, i + UPSERT_CHUNK_SIZE);
5589
- if (slice.length === 0) {
5590
- continue;
5591
- }
5592
- await tx.insert(usageHourTable).values(
5593
- slice.map((bucket) => ({
5594
- userId: input.userId,
5595
- deviceId: input.deviceId,
5596
- harness: bucket.harness,
5597
- model: bucket.model,
5598
- hourUtc: new Date(bucket.hourUtc),
5599
- inputTokens: bucket.inputTokens,
5600
- outputTokens: bucket.outputTokens,
5601
- cacheReadTokens: bucket.cacheReadTokens,
5602
- cacheCreateTokens: bucket.cacheCreateTokens,
5603
- sessionCount: bucket.sessionCount
5604
- }))
5605
- ).onConflictDoUpdate({
5606
- target: [
5607
- usageHourTable.userId,
5608
- usageHourTable.deviceId,
5609
- usageHourTable.harness,
5610
- usageHourTable.model,
5611
- usageHourTable.hourUtc
5612
- ],
5613
- set: {
5614
- inputTokens: sql`excluded.input_tokens`,
5615
- outputTokens: sql`excluded.output_tokens`,
5616
- cacheReadTokens: sql`excluded.cache_read_tokens`,
5617
- cacheCreateTokens: sql`excluded.cache_create_tokens`,
5618
- sessionCount: sql`excluded.session_count`,
5619
- updatedAt: sql`now()`
5620
- }
5621
- });
5622
- }
5623
- }
5624
- async function upsertUsageSessionChunks(tx, input) {
5625
- for (let i = 0; i < input.sessions.length; i += UPSERT_CHUNK_SIZE) {
5626
- const slice = input.sessions.slice(i, i + UPSERT_CHUNK_SIZE);
5627
- if (slice.length === 0) {
5628
- continue;
5629
- }
5630
- await tx.insert(usageSessionTable).values(
5631
- slice.map((session) => ({
5632
- userId: input.userId,
5633
- deviceId: input.deviceId,
5634
- harness: session.harness,
5635
- sessionKey: session.sessionKey,
5636
- startedAt: new Date(session.startedAt),
5637
- lastSeenAt: new Date(session.lastSeenAt)
5638
- }))
5639
- ).onConflictDoUpdate({
5640
- target: [
5641
- usageSessionTable.userId,
5642
- usageSessionTable.deviceId,
5643
- usageSessionTable.harness,
5644
- usageSessionTable.sessionKey
5645
- ],
5646
- set: {
5647
- startedAt: sql`least(${usageSessionTable.startedAt}, excluded.started_at)`,
5648
- lastSeenAt: sql`greatest(${usageSessionTable.lastSeenAt}, excluded.last_seen_at)`,
5649
- updatedAt: sql`now()`
5650
- }
5651
- });
5652
- }
5653
- }
5654
- async function assertDeviceDayTokenQuota(tx, input) {
5655
- if (input.days.length === 0 || syncUploadLimits.maxDeviceDayTokens === null) {
5656
- return;
5657
- }
5658
- const { maxDeviceDayTokens } = syncUploadLimits;
5659
- const tokenQuotaRows = await tx.execute(sql`
5660
- select
5661
- (uh.hour_utc at time zone 'UTC')::date::text as day,
5662
- sum(uh.input_tokens + uh.output_tokens + uh.cache_read_tokens + uh.cache_create_tokens)::text as "totalTokens"
5663
- from usage_hour uh
5664
- where uh.user_id = ${input.userId}
5665
- and uh.device_id = ${input.deviceId}
5666
- and (uh.hour_utc at time zone 'UTC')::date in (${daySqlList(input.days)})
5667
- group by 1
5668
- having sum(uh.input_tokens + uh.output_tokens + uh.cache_read_tokens + uh.cache_create_tokens) > ${maxDeviceDayTokens}
5669
- `);
5670
- const [quotaRow] = tokenQuotaRows.rows;
5671
- if (quotaRow) {
5672
- throw new SyncQuotaExceededError({
5673
- message: `device ${input.deviceName} exceeds the daily token quota for ${quotaRow.day}: ${quotaRow.totalTokens} tokens`
5674
- });
5675
- }
5676
- }
5677
- async function assertDeviceDaySessionQuota(tx, input) {
5678
- if (input.days.length === 0) {
5679
- return;
5680
- }
5681
- const sessionQuotaRows = await tx.execute(sql`
5682
- select
5683
- (us.started_at at time zone 'UTC')::date::text as day,
5684
- count(*)::int as "sessionCount"
5685
- from usage_session us
5686
- where us.user_id = ${input.userId}
5687
- and us.device_id = ${input.deviceId}
5688
- and (us.started_at at time zone 'UTC')::date in (${daySqlList(input.days)})
5689
- group by 1
5690
- having count(*) > ${syncUploadLimits.maxDeviceDaySessions}
5691
- `);
5692
- const [quotaRow] = sessionQuotaRows.rows;
5693
- if (quotaRow) {
5694
- throw new SyncQuotaExceededError({
5695
- message: `device ${input.deviceName} exceeds the daily session quota for ${quotaRow.day}: ${quotaRow.sessionCount} sessions`
5696
- });
5697
- }
5698
- }
5699
- var makeSyncService = () => ({
5700
- getWatermark: (input) => Effect11.tryPromise({
5701
- try: async () => {
5702
- const [device] = await input.db.insert(deviceTable).values({ userId: input.userId, name: input.device }).onConflictDoUpdate({
5703
- target: [deviceTable.userId, deviceTable.name],
5704
- set: { lastSeen: sql`now()` }
5705
- }).returning({ id: deviceTable.id, sessionKeySalt: deviceTable.sessionKeySalt });
5706
- if (!device) {
5707
- throw new Error("device upsert returned no rows");
5708
- }
5709
- const [row] = await input.db.select({ hourUtc: max(usageHourTable.hourUtc) }).from(usageHourTable).where(and(eq(usageHourTable.userId, input.userId), eq(usageHourTable.deviceId, device.id)));
5710
- return {
5711
- watermarkHourUtc: toIsoString2(row?.hourUtc),
5712
- sessionKeySalt: device.sessionKeySalt
5713
- };
5714
- },
5715
- catch: databaseError5
5716
- }),
5717
- upsertBuckets: (input) => Effect11.gen(function* () {
5718
- yield* Effect11.try({
5719
- try: () => assertSyncPayload(input),
5720
- catch: syncValidationError
5721
- });
5722
- return yield* Effect11.tryPromise({
5723
- try: async () => await input.db.transaction(async (tx) => {
5724
- const [device] = await tx.insert(deviceTable).values({ userId: input.userId, name: input.device }).onConflictDoUpdate({
5725
- target: [deviceTable.userId, deviceTable.name],
5726
- set: { lastSeen: sql`now()` }
5727
- }).returning({ id: deviceTable.id });
5728
- if (!device) {
5729
- throw new Error("device upsert returned no rows");
5730
- }
5731
- await upsertUsageHourChunks(tx, { buckets: input.buckets, userId: input.userId, deviceId: device.id });
5732
- await upsertUsageSessionChunks(tx, {
5733
- sessions: input.sessions,
5734
- userId: input.userId,
5735
- deviceId: device.id
5736
- });
5737
- const bucketDays = unique(input.buckets.map((bucket) => utcDay(bucket.hourUtc)));
5738
- const sessionDays = unique(input.sessions.map((session) => utcDay(session.startedAt)));
5739
- await assertDeviceDayTokenQuota(tx, {
5740
- userId: input.userId,
5741
- deviceId: device.id,
5742
- deviceName: input.device,
5743
- days: bucketDays
5744
- });
5745
- await assertDeviceDaySessionQuota(tx, {
5746
- userId: input.userId,
5747
- deviceId: device.id,
5748
- deviceName: input.device,
5749
- days: sessionDays
5750
- });
5751
- return { upserted: input.buckets.length, upsertedSessions: input.sessions.length };
5752
- }),
5753
- catch: (err) => {
5754
- if (err instanceof SyncQuotaExceededError || err instanceof SyncTimestampRejectedError) {
5755
- return err;
5756
- }
5757
- return databaseError5(err);
5758
- }
5759
- });
5760
- })
5761
- });
5762
- var SyncServiceLive = Layer6.succeed(SyncService, makeSyncService());
5763
-
5764
- // ../../packages/api/src/services/token-auth.ts
5765
- init_esm_shims();
5766
- import { Context as Context7, Effect as Effect12, Layer as Layer7 } from "effect";
5767
- var BEARER_PREFIX = "Bearer ";
5768
- var TOKEN_LOOKUP_LIMIT = 5;
5769
- var TokenAuthService = class extends Context7.Service()(
5770
- "@oopst/api/TokenAuthService"
5771
- ) {
5772
- };
5773
- var databaseError6 = (err) => new DatabaseError({ message: err instanceof Error ? err.message : "Token auth database operation failed" });
5774
- var makeTokenAuthService = () => ({
5775
- authenticate: (input) => Effect12.tryPromise({
5776
- try: async () => {
5777
- if (!input.authorizationHeader?.startsWith(BEARER_PREFIX)) {
5778
- return null;
5779
- }
5780
- const raw = input.authorizationHeader.slice(BEARER_PREFIX.length).trim();
5781
- const prefix = extractPrefix(raw);
5782
- if (prefix === null) {
5783
- return null;
5784
- }
5785
- const rows = await input.db.select({ token: apiTokenTable, user: userTable }).from(apiTokenTable).innerJoin(userTable, eq(apiTokenTable.userId, userTable.id)).where(and(eq(apiTokenTable.prefix, prefix), isNull(apiTokenTable.revokedAt))).limit(TOKEN_LOOKUP_LIMIT);
5786
- for (const row of rows) {
5787
- const ok = await verifyToken(raw, row.token.tokenHash);
5788
- if (ok) {
5789
- await input.db.update(apiTokenTable).set({ lastUsedAt: /* @__PURE__ */ new Date() }).where(eq(apiTokenTable.id, row.token.id));
5790
- return { user: row.user, tokenId: row.token.id };
5791
- }
5792
- }
5793
- return null;
5794
- },
5795
- catch: databaseError6
5796
- })
5797
- });
5798
- var TokenAuthServiceLive = Layer7.succeed(TokenAuthService, makeTokenAuthService());
5799
-
5800
- // ../../packages/api/src/services/tokens.ts
5801
- init_esm_shims();
5802
- import { Context as Context8, Effect as Effect13, Layer as Layer8 } from "effect";
5803
- var TokenService = class extends Context8.Service()("@oopst/api/TokenService") {
5804
- };
5805
- var tokenMetadataSelection = {
5806
- id: apiTokenTable.id,
5807
- name: apiTokenTable.name,
5808
- prefix: apiTokenTable.prefix,
5809
- lastUsedAt: apiTokenTable.lastUsedAt,
5810
- createdAt: apiTokenTable.createdAt,
5811
- revokedAt: apiTokenTable.revokedAt
5812
- };
5813
- var databaseError7 = (err) => new DatabaseError({ message: err instanceof Error ? err.message : "Token database operation failed" });
5814
- var failedCreateTokenError = () => new DatabaseError({ message: "Failed to create token" });
5815
- var tokenNotFoundError = () => new NotFoundError({ message: "Token not found" });
5816
- var makeTokenService = () => ({
5817
- list: (input) => Effect13.tryPromise({
5818
- try: async () => {
5819
- const rows = await input.db.select(tokenMetadataSelection).from(apiTokenTable).where(eq(apiTokenTable.userId, input.userId));
5820
- return { tokens: rows };
5821
- },
5822
- catch: databaseError7
5823
- }),
5824
- create: (input) => Effect13.gen(function* () {
5825
- const generated = generateToken();
5826
- const row = yield* Effect13.tryPromise({
5827
- try: async () => {
5828
- const tokenHash = await generated.hash;
5829
- const [created] = await input.db.insert(apiTokenTable).values({
5830
- userId: input.userId,
5831
- name: input.name,
5832
- tokenHash,
5833
- prefix: generated.prefix
5834
- }).returning(tokenMetadataSelection);
5835
- return created;
5836
- },
5837
- catch: databaseError7
5838
- });
5839
- if (!row) {
5840
- return yield* Effect13.fail(failedCreateTokenError());
5841
- }
5842
- return { token: generated.token, metadata: row };
5843
- }),
5844
- revoke: (input) => Effect13.gen(function* () {
5845
- const result = yield* Effect13.tryPromise({
5846
- try: () => input.db.update(apiTokenTable).set({ revokedAt: /* @__PURE__ */ new Date() }).where(and(eq(apiTokenTable.id, input.id), eq(apiTokenTable.userId, input.userId))).returning({ id: apiTokenTable.id }),
5847
- catch: databaseError7
5848
- });
5849
- if (result.length === 0) {
5850
- return yield* Effect13.fail(tokenNotFoundError());
5851
- }
5852
- return { ok: true };
5853
- })
5854
- });
5855
- var TokenServiceLive = Layer8.succeed(TokenService, makeTokenService());
5856
-
5857
4002
  // src/sync/client.ts
5858
- import { Effect as Effect14, Layer as Layer9 } from "effect";
4003
+ import { Effect as Effect8, Layer as Layer4 } from "effect";
5859
4004
  import { FetchHttpClient, HttpClient, HttpClientRequest } from "effect/unstable/http";
5860
4005
  import { RpcClient, RpcSerialization } from "effect/unstable/rpc";
5861
4006
  var AUTHORIZATION_HEADER = "authorization";
@@ -5865,22 +4010,22 @@ function createClient(options) {
5865
4010
  return {
5866
4011
  sync: {
5867
4012
  getWatermark: {
5868
- mutate: (input) => Effect14.runPromise(
5869
- Effect14.scoped(
5870
- Effect14.gen(function* () {
4013
+ mutate: (input) => Effect8.runPromise(
4014
+ Effect8.scoped(
4015
+ Effect8.gen(function* () {
5871
4016
  const client = yield* RpcClient.make(SyncRpcs);
5872
4017
  return yield* client["sync.getWatermark"](input);
5873
- }).pipe(Effect14.provide(clientLive))
4018
+ }).pipe(Effect8.provide(clientLive))
5874
4019
  )
5875
4020
  )
5876
4021
  },
5877
4022
  upsertBuckets: {
5878
- mutate: (input) => Effect14.runPromise(
5879
- Effect14.scoped(
5880
- Effect14.gen(function* () {
4023
+ mutate: (input) => Effect8.runPromise(
4024
+ Effect8.scoped(
4025
+ Effect8.gen(function* () {
5881
4026
  const client = yield* RpcClient.make(SyncRpcs);
5882
4027
  return yield* client["sync.upsertBuckets"](input);
5883
- }).pipe(Effect14.provide(clientLive))
4028
+ }).pipe(Effect8.provide(clientLive))
5884
4029
  )
5885
4030
  )
5886
4031
  }
@@ -5896,14 +4041,13 @@ function makeClientLive(options) {
5896
4041
  HttpClientRequest.setHeader(AUTHORIZATION_HEADER, `Bearer ${options.token}`)
5897
4042
  )
5898
4043
  )
5899
- }).pipe(Layer9.provide(RpcSerialization.layerJson), Layer9.provide(FetchHttpClient.layer));
4044
+ }).pipe(Layer4.provide(RpcSerialization.layerJson), Layer4.provide(FetchHttpClient.layer));
5900
4045
  }
5901
4046
  function stripTrailingSlash(url) {
5902
4047
  return url.endsWith("/") ? url.slice(0, -1) : url;
5903
4048
  }
5904
4049
 
5905
4050
  // src/sync/errors.ts
5906
- init_esm_shims();
5907
4051
  var SUCCESS_EXIT_CODE = 0;
5908
4052
  var ZERO_BUCKETS_EXIT_CODE = 1;
5909
4053
  var UNAUTHORIZED_EXIT_CODE = 2;
@@ -5956,12 +4100,12 @@ function isNetworkError(err) {
5956
4100
  }
5957
4101
 
5958
4102
  // src/sync/run.ts
5959
- var HOURS_PER_DAY4 = 24;
5960
- var MINUTES_PER_HOUR4 = 60;
5961
- var SECONDS_PER_MINUTE4 = 60;
5962
- var MS_PER_SECOND4 = 1e3;
4103
+ var HOURS_PER_DAY3 = 24;
4104
+ var MINUTES_PER_HOUR3 = 60;
4105
+ var SECONDS_PER_MINUTE3 = 60;
4106
+ var MS_PER_SECOND3 = 1e3;
5963
4107
  var SYNC_BATCH_SIZE = 500;
5964
- var MS_PER_DAY3 = HOURS_PER_DAY4 * MINUTES_PER_HOUR4 * SECONDS_PER_MINUTE4 * MS_PER_SECOND4;
4108
+ var MS_PER_DAY2 = HOURS_PER_DAY3 * MINUTES_PER_HOUR3 * SECONDS_PER_MINUTE3 * MS_PER_SECOND3;
5965
4109
  var SCAN_PROGRESS_SESSION_STEP = 500;
5966
4110
  async function runSync(options) {
5967
4111
  if (!options.token) {
@@ -5984,7 +4128,7 @@ async function runSync(options) {
5984
4128
  } catch (err) {
5985
4129
  return failureFromSyncError(err, options.logger);
5986
4130
  }
5987
- const cutoff = new Date((watermark?.getTime() ?? 0) - options.lookbackDays * MS_PER_DAY3);
4131
+ const cutoff = new Date((watermark?.getTime() ?? 0) - options.lookbackDays * MS_PER_DAY2);
5988
4132
  if (options.verbose) {
5989
4133
  options.logger.info(`watermark=${watermark?.toISOString() ?? "null"} cutoff=${cutoff.toISOString()}`);
5990
4134
  }
@@ -6023,8 +4167,8 @@ async function runSync(options) {
6023
4167
  } catch (err) {
6024
4168
  return failureFromSyncError(err, options.logger);
6025
4169
  }
6026
- const plannedBuckets = batches.reduce((sum2, batch) => sum2 + batch.buckets.length, 0);
6027
- const plannedSessions = batches.reduce((sum2, batch) => sum2 + batch.sessions.length, 0);
4170
+ const plannedBuckets = batches.reduce((sum, batch) => sum + batch.buckets.length, 0);
4171
+ const plannedSessions = batches.reduce((sum, batch) => sum + batch.sessions.length, 0);
6028
4172
  if (plannedBuckets === 0 && options.sourcesExistedHint === true) {
6029
4173
  options.logger.error(
6030
4174
  errorLine(
@@ -6077,7 +4221,7 @@ async function runSync(options) {
6077
4221
  };
6078
4222
  }
6079
4223
  function runSyncEffect(options) {
6080
- return Effect15.tryPromise({
4224
+ return Effect9.tryPromise({
6081
4225
  try: () => runSync(options),
6082
4226
  catch: (err) => err
6083
4227
  });
@@ -6176,52 +4320,46 @@ function failureFromSyncError(err, logger) {
6176
4320
  }
6177
4321
 
6178
4322
  // src/services/sync-program.ts
6179
- var SyncProgram = class extends Context9.Service()("@oopst/cli/SyncProgram") {
4323
+ var SyncProgram = class extends Context4.Service()("@oopst/cli/SyncProgram") {
6180
4324
  };
6181
- var SyncProgramLive = Layer10.succeed(SyncProgram, {
4325
+ var SyncProgramLive = Layer5.succeed(SyncProgram, {
6182
4326
  run: runSyncEffect
6183
4327
  });
6184
4328
  function runSyncProgram(options) {
6185
- return Effect16.gen(function* () {
4329
+ return Effect10.gen(function* () {
6186
4330
  const program = yield* SyncProgram;
6187
4331
  return yield* program.run(options);
6188
- }).pipe(Effect16.provide(SyncProgramLive));
4332
+ }).pipe(Effect10.provide(SyncProgramLive));
6189
4333
  }
6190
4334
 
6191
4335
  // src/sync/parser-factory.ts
6192
- init_esm_shims();
6193
4336
  import { dirname as dirname2, isAbsolute as isAbsolute3, join as join6, matchesGlob, relative } from "path";
6194
4337
 
6195
- // ../../packages/parsers/src/index.ts
6196
- init_esm_shims();
6197
-
6198
4338
  // ../../packages/parsers/src/claude/index.ts
6199
- init_esm_shims();
6200
4339
  import { stat as stat2 } from "fs/promises";
6201
4340
  import { basename, dirname } from "path";
6202
4341
 
6203
4342
  // ../../packages/parsers/src/config.ts
6204
- init_esm_shims();
6205
4343
  import { homedir } from "os";
6206
4344
  import { isAbsolute as isAbsolute2, join as join2 } from "path";
6207
- import process3 from "process";
6208
- import { Config as Config2, ConfigProvider as ConfigProvider2, Effect as Effect17, Schema as Schema15 } from "effect";
6209
- var runtimeEnv2 = process3["env"];
6210
- var RawParserEnvSchema = Schema15.Struct({
4345
+ import process2 from "process";
4346
+ import { Config as Config2, ConfigProvider as ConfigProvider2, Effect as Effect11, Schema as Schema14 } from "effect";
4347
+ var runtimeEnv2 = process2["env"];
4348
+ var RawParserEnvSchema = Schema14.Struct({
6211
4349
  // biome-ignore lint/style/useNamingConvention: ENV vars are SCREAMING_SNAKE_CASE by convention
6212
- CLAUDE_CONFIG_DIR: Schema15.optional(Schema15.Trim),
4350
+ CLAUDE_CONFIG_DIR: Schema14.optional(Schema14.Trim),
6213
4351
  // biome-ignore lint/style/useNamingConvention: ENV vars are SCREAMING_SNAKE_CASE by convention
6214
- HERMES_CODING_AGENT_DIR: Schema15.optional(Schema15.Trim),
4352
+ HERMES_CODING_AGENT_DIR: Schema14.optional(Schema14.Trim),
6215
4353
  // biome-ignore lint/style/useNamingConvention: ENV vars are SCREAMING_SNAKE_CASE by convention
6216
- HERMES_CODING_AGENT_SESSION_DIR: Schema15.optional(Schema15.Trim),
4354
+ HERMES_CODING_AGENT_SESSION_DIR: Schema14.optional(Schema14.Trim),
6217
4355
  // biome-ignore lint/style/useNamingConvention: ENV vars are SCREAMING_SNAKE_CASE by convention
6218
- OPENCODE_DATA_DIR: Schema15.optional(Schema15.Trim),
4356
+ OPENCODE_DATA_DIR: Schema14.optional(Schema14.Trim),
6219
4357
  // biome-ignore lint/style/useNamingConvention: ENV vars are SCREAMING_SNAKE_CASE by convention
6220
- OPENCODE_DB: Schema15.optional(Schema15.Trim),
4358
+ OPENCODE_DB: Schema14.optional(Schema14.Trim),
6221
4359
  // biome-ignore lint/style/useNamingConvention: ENV vars are SCREAMING_SNAKE_CASE by convention
6222
- PI_CODING_AGENT_DIR: Schema15.optional(Schema15.Trim),
4360
+ PI_CODING_AGENT_DIR: Schema14.optional(Schema14.Trim),
6223
4361
  // biome-ignore lint/style/useNamingConvention: ENV vars are SCREAMING_SNAKE_CASE by convention
6224
- PI_CODING_AGENT_SESSION_DIR: Schema15.optional(Schema15.Trim)
4362
+ PI_CODING_AGENT_SESSION_DIR: Schema14.optional(Schema14.Trim)
6225
4363
  });
6226
4364
  var parserEnvConfig = Config2.schema(RawParserEnvSchema);
6227
4365
  var emptyToUndefined = (value) => value === void 0 || value.length === 0 ? void 0 : value;
@@ -6237,10 +4375,10 @@ var toParserConfig = (raw) => ({
6237
4375
  });
6238
4376
  function loadParserConfigEffect(env = runtimeEnv2) {
6239
4377
  const provider = ConfigProvider2.fromEnv({ env: toConfigEnv2(env) });
6240
- return parserEnvConfig.parse(provider).pipe(Effect17.map(toParserConfig));
4378
+ return parserEnvConfig.parse(provider).pipe(Effect11.map(toParserConfig));
6241
4379
  }
6242
4380
  function loadParserConfig(env = runtimeEnv2) {
6243
- return Effect17.runSync(loadParserConfigEffect(env));
4381
+ return Effect11.runSync(loadParserConfigEffect(env));
6244
4382
  }
6245
4383
  function readParserHomeDir() {
6246
4384
  return homedir();
@@ -6273,33 +4411,30 @@ function resolveOpenCodeRoot(config = loadParserConfig(), homeDir = readParserHo
6273
4411
  }
6274
4412
 
6275
4413
  // ../../packages/parsers/src/types.ts
6276
- init_esm_shims();
6277
- import process4 from "process";
4414
+ import process3 from "process";
6278
4415
  function formatLogMeta(meta) {
6279
4416
  return JSON.stringify(meta);
6280
4417
  }
6281
4418
  var consoleLogger = {
6282
4419
  warn: (msg, meta) => {
6283
4420
  if (meta === void 0) {
6284
- process4.stderr.write(`${msg}
4421
+ process3.stderr.write(`${msg}
6285
4422
  `);
6286
4423
  } else {
6287
- process4.stderr.write(`${msg} ${formatLogMeta(meta)}
4424
+ process3.stderr.write(`${msg} ${formatLogMeta(meta)}
6288
4425
  `);
6289
4426
  }
6290
4427
  }
6291
4428
  };
6292
4429
 
6293
4430
  // ../../packages/parsers/src/walk.ts
6294
- init_esm_shims();
6295
- import { Effect as Effect19 } from "effect";
4431
+ import { Effect as Effect13 } from "effect";
6296
4432
 
6297
4433
  // ../../packages/parsers/src/effect/file-walker.ts
6298
- init_esm_shims();
6299
4434
  import { readdir, stat } from "fs/promises";
6300
4435
  import { join as join3 } from "path";
6301
- import { Context as Context10, Effect as Effect18, Layer as Layer11 } from "effect";
6302
- var FileWalker = class extends Context10.Service()("@oopst/parsers/FileWalker") {
4436
+ import { Context as Context5, Effect as Effect12, Layer as Layer6 } from "effect";
4437
+ var FileWalker = class extends Context5.Service()("@oopst/parsers/FileWalker") {
6303
4438
  };
6304
4439
  async function* walkJsonlFiles(root, cutoff) {
6305
4440
  let entries;
@@ -6332,34 +4467,31 @@ async function* walkJsonlFiles(root, cutoff) {
6332
4467
  }
6333
4468
  }
6334
4469
  var makeFileWalker = () => ({
6335
- walk: (root, cutoff) => Effect18.succeed(walkJsonlFiles(root, cutoff))
4470
+ walk: (root, cutoff) => Effect12.succeed(walkJsonlFiles(root, cutoff))
6336
4471
  });
6337
- var FileWalkerLive = Layer11.succeed(FileWalker, makeFileWalker());
4472
+ var FileWalkerLive = Layer6.succeed(FileWalker, makeFileWalker());
6338
4473
 
6339
4474
  // ../../packages/parsers/src/walk.ts
6340
4475
  function walkEffect(root, cutoff) {
6341
- return Effect19.gen(function* () {
4476
+ return Effect13.gen(function* () {
6342
4477
  const walker = yield* FileWalker;
6343
4478
  return yield* walker.walk(root, cutoff);
6344
4479
  });
6345
4480
  }
6346
4481
  async function* walk(root, cutoff) {
6347
- const iterable = await walkEffect(root, cutoff).pipe(Effect19.provide(FileWalkerLive), Effect19.runPromise);
4482
+ const iterable = await walkEffect(root, cutoff).pipe(Effect13.provide(FileWalkerLive), Effect13.runPromise);
6348
4483
  yield* iterable;
6349
4484
  }
6350
4485
 
6351
4486
  // ../../packages/parsers/src/claude/bucketize.ts
6352
- init_esm_shims();
6353
4487
  import { createReadStream as createReadStream2 } from "fs";
6354
4488
  import { createInterface as createInterface2 } from "readline";
6355
4489
 
6356
4490
  // ../../packages/parsers/src/codex/bucketize.ts
6357
- init_esm_shims();
6358
4491
  import { createReadStream } from "fs";
6359
4492
  import { createInterface } from "readline";
6360
4493
 
6361
4494
  // ../../packages/parsers/src/codex/events.ts
6362
- init_esm_shims();
6363
4495
  function isObject(value) {
6364
4496
  return typeof value === "object" && value !== null && !Array.isArray(value);
6365
4497
  }
@@ -6483,17 +4615,17 @@ function startOfUtcHour(d) {
6483
4615
  function key2(hourUtc, model) {
6484
4616
  return `${hourUtc.toISOString()}|${model}`;
6485
4617
  }
6486
- function shouldExcludePath(path2, excludePath) {
6487
- return path2 !== void 0 && excludePath?.(path2) === true;
4618
+ function shouldExcludePath(path, excludePath) {
4619
+ return path !== void 0 && excludePath?.(path) === true;
6488
4620
  }
6489
- async function* bucketizeCodexFile(path2, logger, options = {}) {
4621
+ async function* bucketizeCodexFile(path, logger, options = {}) {
6490
4622
  const buckets = /* @__PURE__ */ new Map();
6491
4623
  let currentModel;
6492
4624
  let sawTurnContext = false;
6493
4625
  let lineNo = 0;
6494
4626
  let sessionStartedAt;
6495
4627
  let sessionLastSeenAt;
6496
- const stream = createReadStream(path2, { encoding: "utf8" });
4628
+ const stream = createReadStream(path, { encoding: "utf8" });
6497
4629
  const rl = createInterface({ input: stream, crlfDelay: Number.POSITIVE_INFINITY });
6498
4630
  try {
6499
4631
  for await (const raw of rl) {
@@ -6506,7 +4638,7 @@ async function* bucketizeCodexFile(path2, logger, options = {}) {
6506
4638
  try {
6507
4639
  parsed = JSON.parse(trimmed);
6508
4640
  } catch {
6509
- logger.warn("malformed jsonl line", { path: path2, line: lineNo });
4641
+ logger.warn("malformed jsonl line", { path, line: lineNo });
6510
4642
  continue;
6511
4643
  }
6512
4644
  if (isCodexSessionMetaEvent(parsed)) {
@@ -6580,7 +4712,7 @@ async function* bucketizeCodexFile(path2, logger, options = {}) {
6580
4712
  if (sessionStartedAt === void 0 || sessionLastSeenAt === void 0) {
6581
4713
  return;
6582
4714
  }
6583
- const sessionIds = /* @__PURE__ */ new Set([path2]);
4715
+ const sessionIds = /* @__PURE__ */ new Set([path]);
6584
4716
  for (const acc of buckets.values()) {
6585
4717
  yield {
6586
4718
  harness: "codex",
@@ -6598,7 +4730,6 @@ async function* bucketizeCodexFile(path2, logger, options = {}) {
6598
4730
  }
6599
4731
 
6600
4732
  // ../../packages/parsers/src/claude/events.ts
6601
- init_esm_shims();
6602
4733
  function isObject2(value) {
6603
4734
  return typeof value === "object" && value !== null && !Array.isArray(value);
6604
4735
  }
@@ -6654,13 +4785,13 @@ function isClaudeAssistantEvent(value) {
6654
4785
  function key3(hourUtc, model) {
6655
4786
  return `${hourUtc.toISOString()}|${model}`;
6656
4787
  }
6657
- async function* bucketizeClaudeFile(path2, logger, options = {}) {
4788
+ async function* bucketizeClaudeFile(path, logger, options = {}) {
6658
4789
  const buckets = /* @__PURE__ */ new Map();
6659
4790
  const seenTuples = options.seenTuples ?? /* @__PURE__ */ new Set();
6660
4791
  let lineNo = 0;
6661
4792
  let sessionStartedAt;
6662
4793
  let sessionLastSeenAt;
6663
- const stream = createReadStream2(path2, { encoding: "utf8" });
4794
+ const stream = createReadStream2(path, { encoding: "utf8" });
6664
4795
  const rl = createInterface2({ input: stream, crlfDelay: Number.POSITIVE_INFINITY });
6665
4796
  try {
6666
4797
  for await (const raw of rl) {
@@ -6673,7 +4804,7 @@ async function* bucketizeClaudeFile(path2, logger, options = {}) {
6673
4804
  try {
6674
4805
  parsed = JSON.parse(trimmed);
6675
4806
  } catch {
6676
- logger.warn("malformed jsonl line", { path: path2, line: lineNo });
4807
+ logger.warn("malformed jsonl line", { path, line: lineNo });
6677
4808
  continue;
6678
4809
  }
6679
4810
  if (!isClaudeAssistantEvent(parsed)) {
@@ -6735,7 +4866,7 @@ async function* bucketizeClaudeFile(path2, logger, options = {}) {
6735
4866
  if (sessionStartedAt === void 0 || sessionLastSeenAt === void 0) {
6736
4867
  return;
6737
4868
  }
6738
- const sessionIds = /* @__PURE__ */ new Set([options.sessionId ?? path2]);
4869
+ const sessionIds = /* @__PURE__ */ new Set([options.sessionId ?? path]);
6739
4870
  for (const acc of buckets.values()) {
6740
4871
  yield {
6741
4872
  harness: "claude_code",
@@ -6753,17 +4884,17 @@ async function* bucketizeClaudeFile(path2, logger, options = {}) {
6753
4884
  }
6754
4885
 
6755
4886
  // ../../packages/parsers/src/claude/index.ts
6756
- async function isFile(path2) {
4887
+ async function isFile(path) {
6757
4888
  try {
6758
- return (await stat2(path2)).isFile();
4889
+ return (await stat2(path)).isFile();
6759
4890
  } catch {
6760
4891
  return false;
6761
4892
  }
6762
4893
  }
6763
- function sourceSessionId(path2) {
6764
- const fileDir = dirname(path2);
4894
+ function sourceSessionId(path) {
4895
+ const fileDir = dirname(path);
6765
4896
  if (basename(fileDir) !== "subagents") {
6766
- return path2;
4897
+ return path;
6767
4898
  }
6768
4899
  const sessionDir = dirname(fileDir);
6769
4900
  return `${sessionDir}.jsonl`;
@@ -6792,12 +4923,11 @@ async function* parseClaude(opts) {
6792
4923
  }
6793
4924
 
6794
4925
  // ../../packages/parsers/src/codex/index.ts
6795
- init_esm_shims();
6796
4926
  import { stat as stat3 } from "fs/promises";
6797
- import { Effect as Effect20 } from "effect";
6798
- async function isFile2(path2) {
4927
+ import { Effect as Effect14 } from "effect";
4928
+ async function isFile2(path) {
6799
4929
  try {
6800
- return (await stat3(path2)).isFile();
4930
+ return (await stat3(path)).isFile();
6801
4931
  } catch {
6802
4932
  return false;
6803
4933
  }
@@ -6805,8 +4935,8 @@ async function isFile2(path2) {
6805
4935
  function parseCodexEffect(opts) {
6806
4936
  const logger = opts.logger ?? consoleLogger;
6807
4937
  const root = opts.root ?? resolveCodexSessionsRoot();
6808
- return Effect20.gen(function* () {
6809
- if (yield* Effect20.tryPromise({ try: () => isFile2(root), catch: (error) => error })) {
4938
+ return Effect14.gen(function* () {
4939
+ if (yield* Effect14.tryPromise({ try: () => isFile2(root), catch: (error) => error })) {
6810
4940
  return bucketizeCodexFile(root, logger, { excludePath: opts.excludePath });
6811
4941
  }
6812
4942
  const roots = [root];
@@ -6830,21 +4960,18 @@ async function* bucketizeCodexSources(sources, logger, options) {
6830
4960
  }
6831
4961
  }
6832
4962
  async function* parseCodex(opts) {
6833
- const iterable = await parseCodexEffect(opts).pipe(Effect20.provide(FileWalkerLive), Effect20.runPromise);
4963
+ const iterable = await parseCodexEffect(opts).pipe(Effect14.provide(FileWalkerLive), Effect14.runPromise);
6834
4964
  yield* iterable;
6835
4965
  }
6836
4966
 
6837
4967
  // ../../packages/parsers/src/opencode/index.ts
6838
- init_esm_shims();
6839
4968
  import { readdir as readdir2, stat as stat4 } from "fs/promises";
6840
4969
  import { basename as basename2, join as join4 } from "path";
6841
4970
 
6842
4971
  // ../../packages/parsers/src/opencode/bucketize.ts
6843
- init_esm_shims();
6844
4972
  import { readFile } from "fs/promises";
6845
4973
 
6846
4974
  // ../../packages/parsers/src/opencode/events.ts
6847
- init_esm_shims();
6848
4975
  function isObject3(value) {
6849
4976
  return typeof value === "object" && value !== null && !Array.isArray(value);
6850
4977
  }
@@ -7044,7 +5171,7 @@ function addUsage(accumulators, usage) {
7044
5171
  }
7045
5172
  function shouldExcludeUsage(usage, sessionPaths, excludePath) {
7046
5173
  const paths = sessionPaths.get(usage.sessionId);
7047
- return paths?.some((path2) => excludePath?.(path2) === true) === true;
5174
+ return paths?.some((path) => excludePath?.(path) === true) === true;
7048
5175
  }
7049
5176
  function* finalizedBuckets(accumulators) {
7050
5177
  for (const acc of accumulators.values()) {
@@ -7113,12 +5240,12 @@ function readSessionPaths(db) {
7113
5240
  }
7114
5241
  return paths;
7115
5242
  }
7116
- async function* bucketizeOpenCodeDatabase(path2, cutoff, logger, excludePath) {
5243
+ async function* bucketizeOpenCodeDatabase(path, cutoff, logger, excludePath) {
7117
5244
  const accumulators = /* @__PURE__ */ new Map();
7118
5245
  const DatabaseSync = await loadDatabaseSync();
7119
5246
  let db;
7120
5247
  try {
7121
- db = new DatabaseSync(path2, { readOnly: true, timeout: 1e3 });
5248
+ db = new DatabaseSync(path, { readOnly: true, timeout: 1e3 });
7122
5249
  const sessionPaths = readSessionPaths(db);
7123
5250
  for (const row of readSessionMessageRows(db, cutoff)) {
7124
5251
  const sessionId = typeof row.sessionId === "string" ? row.sessionId : void 0;
@@ -7127,7 +5254,7 @@ async function* bucketizeOpenCodeDatabase(path2, cutoff, logger, excludePath) {
7127
5254
  try {
7128
5255
  parsed = parseJson(row.data);
7129
5256
  } catch {
7130
- logger.warn("malformed opencode sqlite message", { path: path2 });
5257
+ logger.warn("malformed opencode sqlite message", { path });
7131
5258
  continue;
7132
5259
  }
7133
5260
  const usage = pickOpenCodeUsage(parsed, sessionId, fallbackTimestampMs);
@@ -7137,19 +5264,19 @@ async function* bucketizeOpenCodeDatabase(path2, cutoff, logger, excludePath) {
7137
5264
  }
7138
5265
  } catch (err) {
7139
5266
  if (!isMissingTableError(err)) {
7140
- logger.warn("failed to parse opencode sqlite database", { path: path2 });
5267
+ logger.warn("failed to parse opencode sqlite database", { path });
7141
5268
  }
7142
5269
  } finally {
7143
5270
  db?.close();
7144
5271
  }
7145
5272
  yield* finalizedBuckets(accumulators);
7146
5273
  }
7147
- async function* bucketizeOpenCodeJsonFile(path2, logger) {
5274
+ async function* bucketizeOpenCodeJsonFile(path, logger) {
7148
5275
  let parsed;
7149
5276
  try {
7150
- parsed = JSON.parse(await readFile(path2, "utf8"));
5277
+ parsed = JSON.parse(await readFile(path, "utf8"));
7151
5278
  } catch {
7152
- logger.warn("malformed opencode json file", { path: path2 });
5279
+ logger.warn("malformed opencode json file", { path });
7153
5280
  return;
7154
5281
  }
7155
5282
  const usage = pickOpenCodeUsage(parsed);
@@ -7163,9 +5290,9 @@ async function* bucketizeOpenCodeJsonFile(path2, logger) {
7163
5290
 
7164
5291
  // ../../packages/parsers/src/opencode/index.ts
7165
5292
  var OPENCODE_DB_FILE_PATTERN = /^opencode(?:-[^/]+)?\.db$/u;
7166
- async function pathKind(path2) {
5293
+ async function pathKind(path) {
7167
5294
  try {
7168
- const s = await stat4(path2);
5295
+ const s = await stat4(path);
7169
5296
  if (s.isFile()) {
7170
5297
  return "file";
7171
5298
  }
@@ -7263,17 +5390,14 @@ async function* parseOpenCode(opts) {
7263
5390
  }
7264
5391
 
7265
5392
  // ../../packages/parsers/src/pi/index.ts
7266
- init_esm_shims();
7267
5393
  import { stat as stat5 } from "fs/promises";
7268
5394
  import { basename as basename3, join as join5 } from "path";
7269
5395
 
7270
5396
  // ../../packages/parsers/src/pi/bucketize.ts
7271
- init_esm_shims();
7272
5397
  import { createReadStream as createReadStream3 } from "fs";
7273
5398
  import { createInterface as createInterface3 } from "readline";
7274
5399
 
7275
5400
  // ../../packages/parsers/src/pi/events.ts
7276
- init_esm_shims();
7277
5401
  function isObject4(value) {
7278
5402
  return typeof value === "object" && value !== null && !Array.isArray(value);
7279
5403
  }
@@ -7440,13 +5564,13 @@ function hermesRowToBucket(row, excludePath) {
7440
5564
  sessionLastSeenAt: new Date(lastSeenAtMs)
7441
5565
  };
7442
5566
  }
7443
- async function* bucketizePiStyleFile(path2, harness, logger, options = {}) {
5567
+ async function* bucketizePiStyleFile(path, harness, logger, options = {}) {
7444
5568
  const buckets = /* @__PURE__ */ new Map();
7445
5569
  const seenMessageIds = options.seenMessageIds ?? /* @__PURE__ */ new Set();
7446
5570
  let lineNo = 0;
7447
5571
  let sessionStartedAt;
7448
5572
  let sessionLastSeenAt;
7449
- const stream = createReadStream3(path2, { encoding: "utf8" });
5573
+ const stream = createReadStream3(path, { encoding: "utf8" });
7450
5574
  const rl = createInterface3({ input: stream, crlfDelay: Number.POSITIVE_INFINITY });
7451
5575
  try {
7452
5576
  for await (const raw of rl) {
@@ -7459,7 +5583,7 @@ async function* bucketizePiStyleFile(path2, harness, logger, options = {}) {
7459
5583
  try {
7460
5584
  parsed = JSON.parse(trimmed);
7461
5585
  } catch {
7462
- logger.warn("malformed jsonl line", { path: path2, line: lineNo });
5586
+ logger.warn("malformed jsonl line", { path, line: lineNo });
7463
5587
  continue;
7464
5588
  }
7465
5589
  if (isPiSessionEntry(parsed)) {
@@ -7529,7 +5653,7 @@ async function* bucketizePiStyleFile(path2, harness, logger, options = {}) {
7529
5653
  if (sessionStartedAt === void 0 || sessionLastSeenAt === void 0) {
7530
5654
  return;
7531
5655
  }
7532
- const sessionIds = /* @__PURE__ */ new Set([path2]);
5656
+ const sessionIds = /* @__PURE__ */ new Set([path]);
7533
5657
  for (const acc of buckets.values()) {
7534
5658
  yield {
7535
5659
  harness,
@@ -7545,11 +5669,11 @@ async function* bucketizePiStyleFile(path2, harness, logger, options = {}) {
7545
5669
  };
7546
5670
  }
7547
5671
  }
7548
- async function* bucketizeHermesDatabase(path2, cutoff, logger, excludePath) {
5672
+ async function* bucketizeHermesDatabase(path, cutoff, logger, excludePath) {
7549
5673
  const DatabaseSync = await loadDatabaseSync2();
7550
5674
  let db;
7551
5675
  try {
7552
- db = new DatabaseSync(path2, { readOnly: true, timeout: 1e3 });
5676
+ db = new DatabaseSync(path, { readOnly: true, timeout: 1e3 });
7553
5677
  for (const row of readHermesSessionRows(db, cutoff)) {
7554
5678
  const bucket = hermesRowToBucket(row, excludePath);
7555
5679
  if (bucket !== void 0) {
@@ -7557,16 +5681,16 @@ async function* bucketizeHermesDatabase(path2, cutoff, logger, excludePath) {
7557
5681
  }
7558
5682
  }
7559
5683
  } catch {
7560
- logger.warn("failed to parse hermes sqlite database", { path: path2 });
5684
+ logger.warn("failed to parse hermes sqlite database", { path });
7561
5685
  } finally {
7562
5686
  db?.close();
7563
5687
  }
7564
5688
  }
7565
5689
 
7566
5690
  // ../../packages/parsers/src/pi/index.ts
7567
- async function pathKind2(path2) {
5691
+ async function pathKind2(path) {
7568
5692
  try {
7569
- const s = await stat5(path2);
5693
+ const s = await stat5(path);
7570
5694
  if (s.isFile()) {
7571
5695
  return "file";
7572
5696
  }
@@ -7578,8 +5702,8 @@ async function pathKind2(path2) {
7578
5702
  return "missing";
7579
5703
  }
7580
5704
  }
7581
- async function isFile3(path2) {
7582
- return await pathKind2(path2) === "file";
5705
+ async function isFile3(path) {
5706
+ return await pathKind2(path) === "file";
7583
5707
  }
7584
5708
  async function* parsePiStyle(opts, harness, defaultRoot) {
7585
5709
  const logger = opts.logger ?? consoleLogger;
@@ -7651,37 +5775,36 @@ async function* parseHermes(opts) {
7651
5775
  }
7652
5776
 
7653
5777
  // src/sync/parser-factory.ts
7654
- import { Effect as Effect22 } from "effect";
5778
+ import { Effect as Effect16 } from "effect";
7655
5779
 
7656
5780
  // src/services/parser-sources.ts
7657
- init_esm_shims();
7658
5781
  import { existsSync, readdirSync, statSync } from "fs";
7659
5782
  import { homedir as homedir2 } from "os";
7660
- import { Context as Context11, Effect as Effect21, Layer as Layer12 } from "effect";
7661
- var ParserSources = class extends Context11.Service()("@oopst/cli/ParserSources") {
5783
+ import { Context as Context6, Effect as Effect15, Layer as Layer7 } from "effect";
5784
+ var ParserSources = class extends Context6.Service()("@oopst/cli/ParserSources") {
7662
5785
  };
7663
5786
  function makeParserSources() {
7664
5787
  return {
7665
- homeDir: Effect21.sync(() => homedir2()),
7666
- cliEnv: Effect21.sync(() => readCliEnv()),
7667
- exists: (path2) => Effect21.sync(() => existsSync(path2)),
7668
- isFile: (path2) => Effect21.sync(() => {
5788
+ homeDir: Effect15.sync(() => homedir2()),
5789
+ cliEnv: Effect15.sync(() => readCliEnv()),
5790
+ exists: (path) => Effect15.sync(() => existsSync(path)),
5791
+ isFile: (path) => Effect15.sync(() => {
7669
5792
  try {
7670
- return statSync(path2).isFile();
5793
+ return statSync(path).isFile();
7671
5794
  } catch {
7672
5795
  return false;
7673
5796
  }
7674
5797
  }),
7675
- readDir: (path2) => Effect21.sync(() => {
5798
+ readDir: (path) => Effect15.sync(() => {
7676
5799
  try {
7677
- return readdirSync(path2);
5800
+ return readdirSync(path);
7678
5801
  } catch {
7679
5802
  return [];
7680
5803
  }
7681
5804
  })
7682
5805
  };
7683
5806
  }
7684
- var ParserSourcesLive = Layer12.succeed(ParserSources, makeParserSources());
5807
+ var ParserSourcesLive = Layer7.succeed(ParserSources, makeParserSources());
7685
5808
 
7686
5809
  // src/sync/parser-factory.ts
7687
5810
  var OPENCODE_DB_FILE_PATTERN2 = /^opencode(?:-[^/]+)?\.db$/u;
@@ -7704,7 +5827,7 @@ function openCodeRoot(home, env) {
7704
5827
  return isAbsolute3(dbPath) ? dbPath : join6(dataRoot, dbPath);
7705
5828
  }
7706
5829
  function hasOpenCodeDatabaseEffect(root) {
7707
- return Effect22.gen(function* () {
5830
+ return Effect16.gen(function* () {
7708
5831
  const sources = yield* ParserSources;
7709
5832
  const entries = yield* sources.readDir(root);
7710
5833
  for (const entry of entries) {
@@ -7717,9 +5840,9 @@ function hasOpenCodeDatabaseEffect(root) {
7717
5840
  }
7718
5841
  function openCodeSourceExistsEffect(root) {
7719
5842
  if (root === ":memory:") {
7720
- return Effect22.succeed(false);
5843
+ return Effect16.succeed(false);
7721
5844
  }
7722
- return Effect22.gen(function* () {
5845
+ return Effect16.gen(function* () {
7723
5846
  const sources = yield* ParserSources;
7724
5847
  if (yield* sources.isFile(root)) {
7725
5848
  return true;
@@ -7728,26 +5851,26 @@ function openCodeSourceExistsEffect(root) {
7728
5851
  });
7729
5852
  }
7730
5853
  function hermesSourceExistsEffect(root) {
7731
- return Effect22.gen(function* () {
5854
+ return Effect16.gen(function* () {
7732
5855
  const sources = yield* ParserSources;
7733
5856
  return (yield* sources.isFile(root)) || (yield* sources.exists(join6(root, "state.db"))) || (yield* sources.exists(join6(root, "sessions"))) || (yield* sources.exists(join6(root, "agent", "sessions")));
7734
5857
  });
7735
5858
  }
7736
- function isPathInsideOrEqual(path2, parent) {
7737
- const rel = relative(parent, path2);
5859
+ function isPathInsideOrEqual(path, parent) {
5860
+ const rel = relative(parent, path);
7738
5861
  return rel === "" || !(rel.startsWith("..") || isAbsolute3(rel));
7739
5862
  }
7740
- function comparableLocalPath(path2, home) {
7741
- if (!(path2 === "~" || path2.startsWith("~/") || isAbsolute3(path2))) {
5863
+ function comparableLocalPath(path, home) {
5864
+ if (!(path === "~" || path.startsWith("~/") || isAbsolute3(path))) {
7742
5865
  return void 0;
7743
5866
  }
7744
- return normalizeConfigPath(path2, home);
5867
+ return normalizeConfigPath(path, home);
7745
5868
  }
7746
- function hasGlobPattern(path2) {
7747
- return GLOB_PATTERN.test(path2);
5869
+ function hasGlobPattern(path) {
5870
+ return GLOB_PATTERN.test(path);
7748
5871
  }
7749
- function matchesPathOrAncestorGlob(path2, pattern) {
7750
- let current = path2;
5872
+ function matchesPathOrAncestorGlob(path, pattern) {
5873
+ let current = path;
7751
5874
  for (; ; ) {
7752
5875
  if (matchesGlob(current, pattern)) {
7753
5876
  return true;
@@ -7760,15 +5883,15 @@ function matchesPathOrAncestorGlob(path2, pattern) {
7760
5883
  }
7761
5884
  }
7762
5885
  function createExcludeMatcher(options) {
7763
- const normalizedExclude = options.exclude.map((path2) => {
7764
- const normalizedPath = normalizeConfigPath(path2, options.home);
5886
+ const normalizedExclude = options.exclude.map((path) => {
5887
+ const normalizedPath = normalizeConfigPath(path, options.home);
7765
5888
  return {
7766
5889
  isGlob: hasGlobPattern(normalizedPath),
7767
5890
  path: normalizedPath
7768
5891
  };
7769
5892
  });
7770
- return (path2) => {
7771
- const comparable = comparableLocalPath(path2, options.home);
5893
+ return (path) => {
5894
+ const comparable = comparableLocalPath(path, options.home);
7772
5895
  if (comparable === void 0) {
7773
5896
  return false;
7774
5897
  }
@@ -7778,7 +5901,7 @@ function createExcludeMatcher(options) {
7778
5901
  };
7779
5902
  }
7780
5903
  function resolveParserSourcePlanEffect(options = {}) {
7781
- return Effect22.gen(function* () {
5904
+ return Effect16.gen(function* () {
7782
5905
  const sources = yield* ParserSources;
7783
5906
  const home = yield* sources.homeDir;
7784
5907
  const env = yield* sources.cliEnv;
@@ -7826,10 +5949,10 @@ function buildFactoryFromPlan(plan) {
7826
5949
  });
7827
5950
  }
7828
5951
  function buildRealParserFactoryEffect(options = {}) {
7829
- return Effect22.map(resolveParserSourcePlanEffect(options), buildFactoryFromPlan);
5952
+ return Effect16.map(resolveParserSourcePlanEffect(options), buildFactoryFromPlan);
7830
5953
  }
7831
5954
  function buildRealParserFactory(options = {}) {
7832
- return buildRealParserFactoryEffect(options).pipe(Effect22.provide(ParserSourcesLive), Effect22.runSync);
5955
+ return buildRealParserFactoryEffect(options).pipe(Effect16.provide(ParserSourcesLive), Effect16.runSync);
7833
5956
  }
7834
5957
 
7835
5958
  // src/index.ts
@@ -7855,24 +5978,24 @@ var cliOutputFormatter = {
7855
5978
  ...CliOutput.defaultFormatter({ colors: false }),
7856
5979
  formatVersion: (_name, version) => version
7857
5980
  };
7858
- var CliRuntimeLayer = Layer13.mergeAll(NodeServices.layer, CliOutput.layer(cliOutputFormatter));
5981
+ var CliRuntimeLayer = Layer8.mergeAll(NodeServices.layer, CliOutput.layer(cliOutputFormatter));
7859
5982
  function optionalValue(value) {
7860
5983
  return Option2.getOrUndefined(value);
7861
5984
  }
7862
5985
  function writeStdoutLine(msg) {
7863
- process5.stdout.write(`${msg}
5986
+ process4.stdout.write(`${msg}
7864
5987
  `);
7865
5988
  }
7866
5989
  function writeStderrLine(msg) {
7867
- process5.stderr.write(`${msg}
5990
+ process4.stderr.write(`${msg}
7868
5991
  `);
7869
5992
  }
7870
5993
  function writeUnknownError(err) {
7871
5994
  writeStderrLine(err instanceof Error ? err.stack ?? err.message : String(err));
7872
5995
  }
7873
5996
  function isEntrypoint() {
7874
- const [, argvPath] = process5.argv;
7875
- return argvPath ? realpathSync(fileURLToPath2(import.meta.url)) === realpathSync(argvPath) : false;
5997
+ const [, argvPath] = process4.argv;
5998
+ return argvPath ? realpathSync(fileURLToPath(import.meta.url)) === realpathSync(argvPath) : false;
7876
5999
  }
7877
6000
  function parseHarnessFilter(value) {
7878
6001
  if (value === void 0) {
@@ -7909,7 +6032,7 @@ async function runSyncCommand(raw) {
7909
6032
  sourcesExistedHint = real2.anySourceExisted;
7910
6033
  return real2;
7911
6034
  };
7912
- const result = await Effect23.runPromise(
6035
+ const result = await Effect17.runPromise(
7913
6036
  runSyncProgram({
7914
6037
  token,
7915
6038
  device,
@@ -7918,7 +6041,7 @@ async function runSyncCommand(raw) {
7918
6041
  harness,
7919
6042
  dryRun: raw.dryRun,
7920
6043
  verbose: raw.verbose,
7921
- color: process5.stdout.isTTY === true,
6044
+ color: process4.stdout.isTTY === true,
7922
6045
  logger: {
7923
6046
  info: writeStdoutLine,
7924
6047
  error: writeStderrLine
@@ -7982,8 +6105,8 @@ function buildCli() {
7982
6105
  dryRun: dryRunFlag,
7983
6106
  verbose: verboseFlag
7984
6107
  },
7985
- (raw) => Effect23.promise(() => runSyncCommand(raw)).pipe(
7986
- Effect23.flatMap((exitCode) => exitCode === EXIT.success ? Effect23.void : Effect23.fail(new CliExit(exitCode)))
6108
+ (raw) => Effect17.promise(() => runSyncCommand(raw)).pipe(
6109
+ Effect17.flatMap((exitCode) => exitCode === EXIT.success ? Effect17.void : Effect17.fail(new CliExit(exitCode)))
7987
6110
  )
7988
6111
  ).pipe(Command.withDescription("Scan local AI coding harness logs and upload hourly usage records"));
7989
6112
  return Command.make("oopst").pipe(
@@ -7992,7 +6115,7 @@ function buildCli() {
7992
6115
  );
7993
6116
  }
7994
6117
  if (isEntrypoint()) {
7995
- buildCli().pipe(Command.run({ version: VERSION }), Effect23.provide(CliRuntimeLayer), NodeRuntime.runMain);
6118
+ buildCli().pipe(Command.run({ version: VERSION }), Effect17.provide(CliRuntimeLayer), NodeRuntime.runMain);
7996
6119
  }
7997
6120
  export {
7998
6121
  buildCli