@cookielab.io/oopst 0.4.0 → 0.5.0

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
- import { readFileSync as readFileSync2, realpathSync } from "fs";
6
+ import { readFileSync as readFileSync3, realpathSync } from "fs";
521
7
  import process5 from "process";
522
- import { fileURLToPath as fileURLToPath2 } from "url";
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
- // ../../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();
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_b88542aae6c05f0832f8498132552c4c/node_modules/drizzle-orm/entity.js
918
427
  var entityKind = /* @__PURE__ */ Symbol.for("drizzle:entityKind");
919
428
  function is(value, type) {
920
429
  if (!value || typeof value !== "object") return false;
@@ -928,8 +437,7 @@ function is(value, type) {
928
437
  return false;
929
438
  }
930
439
 
931
- // ../../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();
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_b88542aae6c05f0832f8498132552c4c/node_modules/drizzle-orm/subquery.js
933
441
  var Subquery = class {
934
442
  static [entityKind] = "Subquery";
935
443
  constructor(sql2, fields, alias, isWith = false, usedTables = []) {
@@ -947,14 +455,10 @@ 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
- // ../../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();
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_b88542aae6c05f0832f8498132552c4c/node_modules/drizzle-orm/column-common.js
955
459
  var OriginalColumn = /* @__PURE__ */ Symbol.for("drizzle:OriginalColumn");
956
460
 
957
- // ../../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
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_b88542aae6c05f0832f8498132552c4c/node_modules/drizzle-orm/column.js
958
462
  var noop = (v) => v;
959
463
  noop.isNoop = true;
960
464
  var Column = class {
@@ -1026,14 +530,10 @@ 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
- // ../../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();
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_b88542aae6c05f0832f8498132552c4c/node_modules/drizzle-orm/table.utils.js
1034
534
  var TableName = /* @__PURE__ */ Symbol.for("drizzle:Name");
1035
535
 
1036
- // ../../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
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_b88542aae6c05f0832f8498132552c4c/node_modules/drizzle-orm/table.js
1037
537
  var TableSchema = /* @__PURE__ */ Symbol.for("drizzle:Schema");
1038
538
  var TableColumns = /* @__PURE__ */ Symbol.for("drizzle:Columns");
1039
539
  var ExtraConfigColumns = /* @__PURE__ */ Symbol.for("drizzle:ExtraConfigColumns");
@@ -1089,28 +589,20 @@ 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
- // ../../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();
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_b88542aae6c05f0832f8498132552c4c/node_modules/drizzle-orm/tracing-utils.js
1100
593
  function iife(fn, ...args) {
1101
594
  return fn(...args);
1102
595
  }
1103
596
 
1104
- // ../../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
597
+ // ../../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_b88542aae6c05f0832f8498132552c4c/node_modules/drizzle-orm/tracing.js
1105
598
  var tracer = { startActiveSpan(name2, fn) {
1106
599
  return fn();
1107
600
  } };
1108
601
 
1109
- // ../../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();
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_b88542aae6c05f0832f8498132552c4c/node_modules/drizzle-orm/view-common.js
1111
603
  var ViewBaseConfig = /* @__PURE__ */ Symbol.for("drizzle:ViewBaseConfig");
1112
604
 
1113
- // ../../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
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_b88542aae6c05f0832f8498132552c4c/node_modules/drizzle-orm/sql/sql.js
1114
606
  var FakePrimitiveParam = class {
1115
607
  static [entityKind] = "FakePrimitiveParam";
1116
608
  };
@@ -1414,7 +906,7 @@ function sql(strings, ...params) {
1414
906
  return new SQL([new StringChunk(str)]);
1415
907
  }
1416
908
  _sql.raw = raw;
1417
- function join7(chunks, separator) {
909
+ function join8(chunks, separator) {
1418
910
  const result = [];
1419
911
  for (const [i, chunk] of chunks.entries()) {
1420
912
  if (i > 0 && separator !== void 0) result.push(separator);
@@ -1422,7 +914,7 @@ function sql(strings, ...params) {
1422
914
  }
1423
915
  return new SQL(result);
1424
916
  }
1425
- _sql.join = join7;
917
+ _sql.join = join8;
1426
918
  function identifier(value) {
1427
919
  return new Name(value);
1428
920
  }
@@ -1563,8 +1055,7 @@ Subquery.prototype.getSQL = function() {
1563
1055
  return new SQL([this]);
1564
1056
  };
1565
1057
 
1566
- // ../../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();
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_b88542aae6c05f0832f8498132552c4c/node_modules/drizzle-orm/sql/expressions/conditions.js
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
- // ../../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();
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_b88542aae6c05f0832f8498132552c4c/node_modules/drizzle-orm/utils.js
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
- // ../../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();
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_b88542aae6c05f0832f8498132552c4c/node_modules/drizzle-orm/pg-core/foreign-keys.js
1626
1091
  var ForeignKeyBuilder = class {
1627
1092
  static [entityKind] = "PgForeignKeyBuilder";
1628
1093
  /** @internal */
@@ -1688,7 +1153,7 @@ var ForeignKey = class {
1688
1153
  }
1689
1154
  };
1690
1155
 
1691
- // ../../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
1156
+ // ../../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_b88542aae6c05f0832f8498132552c4c/node_modules/drizzle-orm/pg-core/columns/common.js
1692
1157
  var PgColumnBuilder = class {
1693
1158
  static [entityKind] = "PgColumnBuilder";
1694
1159
  foreignKeyConfigs = [];
@@ -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
- // ../../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();
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_b88542aae6c05f0832f8498132552c4c/node_modules/drizzle-orm/pg-core/columns/int.common.js
1964
1425
  var PgIntColumnBuilder = class extends PgColumnBuilder {
1965
1426
  static [entityKind] = "PgIntColumnBaseBuilder";
1966
1427
  /**
@@ -1999,7 +1460,7 @@ var PgIntColumnBuilder = class extends PgColumnBuilder {
1999
1460
  }
2000
1461
  };
2001
1462
 
2002
- // ../../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
1463
+ // ../../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_b88542aae6c05f0832f8498132552c4c/node_modules/drizzle-orm/pg-core/columns/bigint.js
2003
1464
  var PgBigInt53Builder = class extends PgIntColumnBuilder {
2004
1465
  static [entityKind] = "PgBigInt53Builder";
2005
1466
  constructor(name2) {
@@ -2061,8 +1522,7 @@ function bigint(a, b) {
2061
1522
  return new PgBigInt64Builder(name2);
2062
1523
  }
2063
1524
 
2064
- // ../../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();
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_b88542aae6c05f0832f8498132552c4c/node_modules/drizzle-orm/pg-core/columns/bigserial.js
2066
1526
  var PgBigSerial53Builder = class extends PgColumnBuilder {
2067
1527
  static [entityKind] = "PgBigSerial53Builder";
2068
1528
  constructor(name2) {
@@ -2109,8 +1569,7 @@ function bigserial(a, b) {
2109
1569
  return new PgBigSerial64Builder(name2);
2110
1570
  }
2111
1571
 
2112
- // ../../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();
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_b88542aae6c05f0832f8498132552c4c/node_modules/drizzle-orm/pg-core/columns/boolean.js
2114
1573
  var PgBooleanBuilder = class extends PgColumnBuilder {
2115
1574
  static [entityKind] = "PgBooleanBuilder";
2116
1575
  constructor(name2) {
@@ -2133,8 +1592,7 @@ function boolean(name2) {
2133
1592
  return new PgBooleanBuilder(name2 ?? "");
2134
1593
  }
2135
1594
 
2136
- // ../../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();
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_b88542aae6c05f0832f8498132552c4c/node_modules/drizzle-orm/pg-core/columns/char.js
2138
1596
  var PgCharBuilder = class extends PgColumnBuilder {
2139
1597
  static [entityKind] = "PgCharBuilder";
2140
1598
  constructor(name2, config) {
@@ -2168,8 +1626,7 @@ function char(a, b = {}) {
2168
1626
  return new PgCharBuilder(name2, config);
2169
1627
  }
2170
1628
 
2171
- // ../../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();
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_b88542aae6c05f0832f8498132552c4c/node_modules/drizzle-orm/pg-core/columns/cidr.js
2173
1630
  var PgCidrBuilder = class extends PgColumnBuilder {
2174
1631
  static [entityKind] = "PgCidrBuilder";
2175
1632
  constructor(name2) {
@@ -2192,8 +1649,7 @@ function cidr(name2) {
2192
1649
  return new PgCidrBuilder(name2 ?? "");
2193
1650
  }
2194
1651
 
2195
- // ../../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();
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_b88542aae6c05f0832f8498132552c4c/node_modules/drizzle-orm/pg-core/array.js
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
- // ../../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();
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_b88542aae6c05f0832f8498132552c4c/node_modules/drizzle-orm/pg-core/columns/postgis_extension/utils.js
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));
@@ -2300,7 +1749,7 @@ function parseEWKB(hex) {
2300
1749
  throw new Error("Unsupported geometry type");
2301
1750
  }
2302
1751
 
2303
- // ../../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
1752
+ // ../../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_b88542aae6c05f0832f8498132552c4c/node_modules/drizzle-orm/pg-core/codecs.js
2304
1753
  var PG_ALIAS_TO_TYPE_MAP = {
2305
1754
  int2: "smallint",
2306
1755
  integer: "int",
@@ -2566,7 +2015,7 @@ var genericPgCodecs = {
2566
2015
  }
2567
2016
  };
2568
2017
 
2569
- // ../../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
2018
+ // ../../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_b88542aae6c05f0832f8498132552c4c/node_modules/drizzle-orm/pg-core/columns/custom.js
2570
2019
  var PgCustomColumnBuilder = class extends PgColumnBuilder {
2571
2020
  static [entityKind] = "PgCustomColumnBuilder";
2572
2021
  constructor(name2, fieldConfig, customTypeParams) {
@@ -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
- // ../../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();
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_b88542aae6c05f0832f8498132552c4c/node_modules/drizzle-orm/pg-core/columns/date.common.js
2625
2070
  var PgDateColumnBuilder = class extends PgColumnBuilder {
2626
2071
  static [entityKind] = "PgDateColumnBaseBuilder";
2627
2072
  /**
@@ -2633,7 +2078,7 @@ var PgDateColumnBuilder = class extends PgColumnBuilder {
2633
2078
  }
2634
2079
  };
2635
2080
 
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/date.js
2081
+ // ../../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_b88542aae6c05f0832f8498132552c4c/node_modules/drizzle-orm/pg-core/columns/date.js
2637
2082
  var PgDateBuilder = class extends PgDateColumnBuilder {
2638
2083
  static [entityKind] = "PgDateBuilder";
2639
2084
  constructor(name2) {
@@ -2684,8 +2129,7 @@ function date(a, b) {
2684
2129
  return new PgDateStringBuilder(name2);
2685
2130
  }
2686
2131
 
2687
- // ../../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();
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_b88542aae6c05f0832f8498132552c4c/node_modules/drizzle-orm/pg-core/columns/double-precision.js
2689
2133
  var PgDoublePrecisionBuilder = class extends PgColumnBuilder {
2690
2134
  static [entityKind] = "PgDoublePrecisionBuilder";
2691
2135
  constructor(name2) {
@@ -2708,8 +2152,7 @@ function doublePrecision(name2) {
2708
2152
  return new PgDoublePrecisionBuilder(name2 ?? "");
2709
2153
  }
2710
2154
 
2711
- // ../../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();
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_b88542aae6c05f0832f8498132552c4c/node_modules/drizzle-orm/pg-core/columns/inet.js
2713
2156
  var PgInetBuilder = class extends PgColumnBuilder {
2714
2157
  static [entityKind] = "PgInetBuilder";
2715
2158
  constructor(name2) {
@@ -2732,8 +2175,7 @@ function inet(name2) {
2732
2175
  return new PgInetBuilder(name2 ?? "");
2733
2176
  }
2734
2177
 
2735
- // ../../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();
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_b88542aae6c05f0832f8498132552c4c/node_modules/drizzle-orm/pg-core/columns/integer.js
2737
2179
  var PgIntegerBuilder = class extends PgIntColumnBuilder {
2738
2180
  static [entityKind] = "PgIntegerBuilder";
2739
2181
  constructor(name2) {
@@ -2756,8 +2198,7 @@ function integer(name2) {
2756
2198
  return new PgIntegerBuilder(name2 ?? "");
2757
2199
  }
2758
2200
 
2759
- // ../../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();
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_b88542aae6c05f0832f8498132552c4c/node_modules/drizzle-orm/pg-core/columns/interval.js
2761
2202
  var PgIntervalBuilder = class extends PgColumnBuilder {
2762
2203
  static [entityKind] = "PgIntervalBuilder";
2763
2204
  constructor(name2, intervalConfig) {
@@ -2789,8 +2230,7 @@ function interval(a, b = {}) {
2789
2230
  return new PgIntervalBuilder(name2, config);
2790
2231
  }
2791
2232
 
2792
- // ../../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();
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_b88542aae6c05f0832f8498132552c4c/node_modules/drizzle-orm/pg-core/columns/json.js
2794
2234
  var PgJsonBuilder = class extends PgColumnBuilder {
2795
2235
  static [entityKind] = "PgJsonBuilder";
2796
2236
  constructor(name2) {
@@ -2816,8 +2256,7 @@ function json(name2) {
2816
2256
  return new PgJsonBuilder(name2 ?? "");
2817
2257
  }
2818
2258
 
2819
- // ../../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();
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_b88542aae6c05f0832f8498132552c4c/node_modules/drizzle-orm/pg-core/columns/jsonb.js
2821
2260
  var PgJsonbBuilder = class extends PgColumnBuilder {
2822
2261
  static [entityKind] = "PgJsonbBuilder";
2823
2262
  constructor(name2) {
@@ -2843,8 +2282,7 @@ function jsonb(name2) {
2843
2282
  return new PgJsonbBuilder(name2 ?? "");
2844
2283
  }
2845
2284
 
2846
- // ../../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();
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_b88542aae6c05f0832f8498132552c4c/node_modules/drizzle-orm/pg-core/columns/line.js
2848
2286
  var PgLineBuilder = class extends PgColumnBuilder {
2849
2287
  static [entityKind] = "PgLineBuilder";
2850
2288
  constructor(name2) {
@@ -2895,8 +2333,7 @@ function line(a, b) {
2895
2333
  return new PgLineABCBuilder(name2);
2896
2334
  }
2897
2335
 
2898
- // ../../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();
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_b88542aae6c05f0832f8498132552c4c/node_modules/drizzle-orm/pg-core/columns/macaddr.js
2900
2337
  var PgMacaddrBuilder = class extends PgColumnBuilder {
2901
2338
  static [entityKind] = "PgMacaddrBuilder";
2902
2339
  constructor(name2) {
@@ -2919,8 +2356,7 @@ function macaddr(name2) {
2919
2356
  return new PgMacaddrBuilder(name2 ?? "");
2920
2357
  }
2921
2358
 
2922
- // ../../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();
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_b88542aae6c05f0832f8498132552c4c/node_modules/drizzle-orm/pg-core/columns/macaddr8.js
2924
2360
  var PgMacaddr8Builder = class extends PgColumnBuilder {
2925
2361
  static [entityKind] = "PgMacaddr8Builder";
2926
2362
  constructor(name2) {
@@ -2943,8 +2379,7 @@ function macaddr8(name2) {
2943
2379
  return new PgMacaddr8Builder(name2 ?? "");
2944
2380
  }
2945
2381
 
2946
- // ../../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();
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_b88542aae6c05f0832f8498132552c4c/node_modules/drizzle-orm/pg-core/columns/numeric.js
2948
2383
  var PgNumericBuilder = class extends PgColumnBuilder {
2949
2384
  static [entityKind] = "PgNumericBuilder";
2950
2385
  constructor(name2, precision, scale) {
@@ -3040,8 +2475,7 @@ function numeric(a, b) {
3040
2475
  return mode === "number" ? new PgNumericNumberBuilder(name2, config?.precision, config?.scale) : mode === "bigint" ? new PgNumericBigIntBuilder(name2, config?.precision, config?.scale) : new PgNumericBuilder(name2, config?.precision, config?.scale);
3041
2476
  }
3042
2477
 
3043
- // ../../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();
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_b88542aae6c05f0832f8498132552c4c/node_modules/drizzle-orm/pg-core/columns/point.js
3045
2479
  var PgPointTupleBuilder = class extends PgColumnBuilder {
3046
2480
  static [entityKind] = "PgPointTupleBuilder";
3047
2481
  constructor(name2) {
@@ -3092,8 +2526,7 @@ function point(a, b) {
3092
2526
  return new PgPointObjectBuilder(name2);
3093
2527
  }
3094
2528
 
3095
- // ../../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();
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_b88542aae6c05f0832f8498132552c4c/node_modules/drizzle-orm/pg-core/columns/postgis_extension/geometry.js
3097
2530
  var PgGeometryBuilder = class extends PgColumnBuilder {
3098
2531
  static [entityKind] = "PgGeometryBuilder";
3099
2532
  constructor(name2, srid) {
@@ -3148,8 +2581,7 @@ function geometry(a, b) {
3148
2581
  return new PgGeometryObjectBuilder(name2, config?.srid);
3149
2582
  }
3150
2583
 
3151
- // ../../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();
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_b88542aae6c05f0832f8498132552c4c/node_modules/drizzle-orm/pg-core/columns/real.js
3153
2585
  var PgRealBuilder = class extends PgColumnBuilder {
3154
2586
  static [entityKind] = "PgRealBuilder";
3155
2587
  constructor(name2, length) {
@@ -3176,8 +2608,7 @@ function real(name2) {
3176
2608
  return new PgRealBuilder(name2 ?? "");
3177
2609
  }
3178
2610
 
3179
- // ../../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();
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_b88542aae6c05f0832f8498132552c4c/node_modules/drizzle-orm/pg-core/columns/serial.js
3181
2612
  var PgSerialBuilder = class extends PgColumnBuilder {
3182
2613
  static [entityKind] = "PgSerialBuilder";
3183
2614
  constructor(name2) {
@@ -3202,8 +2633,7 @@ function serial(name2) {
3202
2633
  return new PgSerialBuilder(name2 ?? "");
3203
2634
  }
3204
2635
 
3205
- // ../../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();
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_b88542aae6c05f0832f8498132552c4c/node_modules/drizzle-orm/pg-core/columns/smallint.js
3207
2637
  var PgSmallIntBuilder = class extends PgIntColumnBuilder {
3208
2638
  static [entityKind] = "PgSmallIntBuilder";
3209
2639
  constructor(name2) {
@@ -3226,8 +2656,7 @@ function smallint(name2) {
3226
2656
  return new PgSmallIntBuilder(name2 ?? "");
3227
2657
  }
3228
2658
 
3229
- // ../../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();
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_b88542aae6c05f0832f8498132552c4c/node_modules/drizzle-orm/pg-core/columns/smallserial.js
3231
2660
  var PgSmallSerialBuilder = class extends PgColumnBuilder {
3232
2661
  static [entityKind] = "PgSmallSerialBuilder";
3233
2662
  constructor(name2) {
@@ -3252,8 +2681,7 @@ function smallserial(name2) {
3252
2681
  return new PgSmallSerialBuilder(name2 ?? "");
3253
2682
  }
3254
2683
 
3255
- // ../../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();
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_b88542aae6c05f0832f8498132552c4c/node_modules/drizzle-orm/pg-core/columns/text.js
3257
2685
  var PgTextBuilder = class extends PgColumnBuilder {
3258
2686
  static [entityKind] = "PgTextBuilder";
3259
2687
  constructor(name2, config) {
@@ -3283,8 +2711,7 @@ function text(a, b = {}) {
3283
2711
  return new PgTextBuilder(name2, config);
3284
2712
  }
3285
2713
 
3286
- // ../../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();
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_b88542aae6c05f0832f8498132552c4c/node_modules/drizzle-orm/pg-core/columns/time.js
3288
2715
  var PgTimeBuilder = class extends PgDateColumnBuilder {
3289
2716
  static [entityKind] = "PgTimeBuilder";
3290
2717
  constructor(name2, withTimezone, precision) {
@@ -3319,8 +2746,7 @@ function time(a, b = {}) {
3319
2746
  return new PgTimeBuilder(name2, config.withTimezone ?? false, config.precision);
3320
2747
  }
3321
2748
 
3322
- // ../../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();
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_b88542aae6c05f0832f8498132552c4c/node_modules/drizzle-orm/pg-core/columns/timestamp.js
3324
2750
  var PgTimestampBuilder = class extends PgDateColumnBuilder {
3325
2751
  static [entityKind] = "PgTimestampBuilder";
3326
2752
  constructor(name2, withTimezone, precision) {
@@ -3391,8 +2817,7 @@ function timestamp(a, b = {}) {
3391
2817
  return new PgTimestampBuilder(name2, config?.withTimezone ?? false, config?.precision);
3392
2818
  }
3393
2819
 
3394
- // ../../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();
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_b88542aae6c05f0832f8498132552c4c/node_modules/drizzle-orm/pg-core/columns/uuid.js
3396
2821
  var PgUUIDBuilder = class extends PgColumnBuilder {
3397
2822
  static [entityKind] = "PgUUIDBuilder";
3398
2823
  constructor(name2) {
@@ -3421,8 +2846,7 @@ function uuid(name2) {
3421
2846
  return new PgUUIDBuilder(name2 ?? "");
3422
2847
  }
3423
2848
 
3424
- // ../../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();
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_b88542aae6c05f0832f8498132552c4c/node_modules/drizzle-orm/pg-core/columns/varchar.js
3426
2850
  var PgVarcharBuilder = class extends PgColumnBuilder {
3427
2851
  static [entityKind] = "PgVarcharBuilder";
3428
2852
  constructor(name2, config) {
@@ -3453,8 +2877,7 @@ function varchar(a, b = {}) {
3453
2877
  return new PgVarcharBuilder(name2, config);
3454
2878
  }
3455
2879
 
3456
- // ../../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();
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_b88542aae6c05f0832f8498132552c4c/node_modules/drizzle-orm/pg-core/columns/vector_extension/bit.js
3458
2881
  var PgBinaryVectorBuilder = class extends PgColumnBuilder {
3459
2882
  static [entityKind] = "PgBinaryVectorBuilder";
3460
2883
  constructor(name2, config) {
@@ -3480,8 +2903,7 @@ function bit(a, b) {
3480
2903
  return new PgBinaryVectorBuilder(name2, config);
3481
2904
  }
3482
2905
 
3483
- // ../../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();
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_b88542aae6c05f0832f8498132552c4c/node_modules/drizzle-orm/pg-core/columns/vector_extension/halfvec.js
3485
2907
  var PgHalfVectorBuilder = class extends PgColumnBuilder {
3486
2908
  static [entityKind] = "PgHalfVectorBuilder";
3487
2909
  constructor(name2, config) {
@@ -3510,8 +2932,7 @@ function halfvec(a, b) {
3510
2932
  return new PgHalfVectorBuilder(name2, config);
3511
2933
  }
3512
2934
 
3513
- // ../../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();
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_b88542aae6c05f0832f8498132552c4c/node_modules/drizzle-orm/pg-core/columns/vector_extension/sparsevec.js
3515
2936
  var PgSparseVectorBuilder = class extends PgColumnBuilder {
3516
2937
  static [entityKind] = "PgSparseVectorBuilder";
3517
2938
  constructor(name2, config) {
@@ -3537,8 +2958,7 @@ function sparsevec(a, b) {
3537
2958
  return new PgSparseVectorBuilder(name2, config);
3538
2959
  }
3539
2960
 
3540
- // ../../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();
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_b88542aae6c05f0832f8498132552c4c/node_modules/drizzle-orm/pg-core/columns/vector_extension/vector.js
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
- // ../../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();
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_b88542aae6c05f0832f8498132552c4c/node_modules/drizzle-orm/pg-core/columns/all.js
3575
2991
  function getPgColumnBuilders() {
3576
2992
  return {
3577
2993
  bigint,
@@ -3609,8 +3025,7 @@ function getPgColumnBuilders() {
3609
3025
  };
3610
3026
  }
3611
3027
 
3612
- // ../../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();
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_b88542aae6c05f0832f8498132552c4c/node_modules/drizzle-orm/casing.js
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
  }
@@ -3625,7 +3040,7 @@ function getCasingFn(casing) {
3625
3040
  return (name2) => name2;
3626
3041
  }
3627
3042
 
3628
- // ../../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
3043
+ // ../../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_b88542aae6c05f0832f8498132552c4c/node_modules/drizzle-orm/pg-core/table.js
3629
3044
  var InlineForeignKeys = /* @__PURE__ */ Symbol.for("drizzle:PgInlineForeignKeys");
3630
3045
  var EnableRLS = /* @__PURE__ */ Symbol.for("drizzle:EnableRLS");
3631
3046
  var PgTable = class extends Table {
@@ -3682,8 +3097,7 @@ function pgTableWithCasing(casing) {
3682
3097
  }
3683
3098
  var pgTable = pgTableWithCasing(void 0);
3684
3099
 
3685
- // ../../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();
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_b88542aae6c05f0832f8498132552c4c/node_modules/drizzle-orm/pg-core/primary-keys.js
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);
@@ -3719,8 +3133,7 @@ var PrimaryKey = class {
3719
3133
  }
3720
3134
  };
3721
3135
 
3722
- // ../../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();
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_b88542aae6c05f0832f8498132552c4c/node_modules/drizzle-orm/pg-core/indexes.js
3724
3137
  var IndexBuilderOn = class {
3725
3138
  static [entityKind] = "PgIndexBuilderOn";
3726
3139
  constructor(unique2, name2) {
@@ -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,153 +3409,27 @@ 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);
3412
+ // ../../packages/api/src/services/auth.ts
3413
+ var AuthService = class extends Context2.Service()("@oopst/api/AuthService") {
3414
+ };
3415
+ var databaseError2 = (err) => new DatabaseError({ message: err instanceof Error ? err.message : "Auth database operation failed" });
3416
+ var failedUpdateProfileError = () => new DatabaseError({ message: "Failed to update profile" });
3417
+ function toAuthUserOutput(user) {
4070
3418
  return {
4071
- token,
4072
- prefix,
4073
- hash: import_argon22.default.hash(token, HASH_OPTIONS)
3419
+ user: {
3420
+ id: user.id,
3421
+ email: user.email,
3422
+ displayName: user.displayName,
3423
+ createdAt: user.createdAt
3424
+ }
4074
3425
  };
4075
3426
  }
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) {
3427
+ function normalizeDisplayName(displayName) {
3428
+ if (displayName === null) {
4089
3429
  return null;
4090
3430
  }
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
- // ../../packages/api/src/services/auth.ts
4168
- init_esm_shims();
4169
- import { Context as Context2, Effect as Effect4, Layer as Layer2 } from "effect";
4170
- var AuthService = class extends Context2.Service()("@oopst/api/AuthService") {
4171
- };
4172
- var databaseError2 = (err) => new DatabaseError({ message: err instanceof Error ? err.message : "Auth database operation failed" });
4173
- var failedUpdateProfileError = () => new DatabaseError({ message: "Failed to update profile" });
4174
- function toAuthUserOutput(user) {
4175
- return {
4176
- user: {
4177
- id: user.id,
4178
- email: user.email,
4179
- displayName: user.displayName,
4180
- createdAt: user.createdAt
4181
- }
4182
- };
4183
- }
4184
- function normalizeDisplayName(displayName) {
4185
- if (displayName === null) {
4186
- return null;
4187
- }
4188
- const trimmed = displayName.trim();
4189
- return trimmed.length === 0 ? null : trimmed;
3431
+ const trimmed = displayName.trim();
3432
+ return trimmed.length === 0 ? null : trimmed;
4190
3433
  }
4191
3434
  var makeAuthService = () => ({
4192
3435
  logout: (input) => Effect4.tryPromise({
@@ -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,287 @@ 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
- // src/sync/parser-factory.ts
6192
- init_esm_shims();
6193
- import { dirname as dirname2, isAbsolute as isAbsolute3, join as join6, matchesGlob, relative } from "path";
4335
+ // src/setup.ts
4336
+ import { spawnSync } from "child_process";
4337
+ import { randomInt } from "crypto";
4338
+ import { chmodSync, existsSync, readFileSync as readFileSync2, writeFileSync } from "fs";
4339
+ import { homedir as readHomedir2, hostname as readHostname2 } from "os";
4340
+ import { dirname, join as join2 } from "path";
4341
+ import process2 from "process";
4342
+ import { createInterface } from "readline/promises";
4343
+ var CRON_START_MARKER = "# OopsT sync start";
4344
+ var CRON_END_MARKER = "# OopsT sync end";
4345
+ var DEFAULT_CRON_PATHS = ["/opt/homebrew/bin", "/usr/local/bin", "/usr/bin", "/bin", "/usr/sbin", "/sbin"];
4346
+ var DEFAULT_PACKAGE_NAME = "@cookielab.io/oopst";
4347
+ var CONFIG_FILE_MODE = 384;
4348
+ var LINE_SPLIT_PATTERN = /\r?\n/u;
4349
+ var SetupError = class extends Error {
4350
+ exitCode;
4351
+ constructor(message, options = {}) {
4352
+ super(message, options);
4353
+ this.name = "SetupError";
4354
+ this.exitCode = options.exitCode ?? EXIT.generalFailure;
4355
+ }
4356
+ };
4357
+ function defaultCommandRunner(command, args, input) {
4358
+ const result = spawnSync(command, [...args], {
4359
+ encoding: "utf8",
4360
+ input
4361
+ });
4362
+ return {
4363
+ status: result.status,
4364
+ stdout: result.stdout ?? "",
4365
+ stderr: result.stderr ?? "",
4366
+ error: result.error
4367
+ };
4368
+ }
4369
+ function writeLine(output, message) {
4370
+ output.write(`${message}
4371
+ `);
4372
+ }
4373
+ function normalizeInput(value) {
4374
+ return value.trim();
4375
+ }
4376
+ function yamlString(value) {
4377
+ return JSON.stringify(value);
4378
+ }
4379
+ function formatSetupConfig(options) {
4380
+ return [
4381
+ "server:",
4382
+ ` api: ${yamlString(options.api)}`,
4383
+ ` token: ${yamlString(options.token)}`,
4384
+ ` device: ${yamlString(options.device)}`,
4385
+ ""
4386
+ ].join("\n");
4387
+ }
4388
+ async function askWithDefault(rl, label, defaultValue) {
4389
+ const answer = normalizeInput(await rl.question(`${label} (${defaultValue}): `));
4390
+ return answer.length > 0 ? answer : defaultValue;
4391
+ }
4392
+ async function askRequired(rl, label) {
4393
+ const answer = normalizeInput(await rl.question(`${label}: `));
4394
+ if (answer.length > 0) {
4395
+ return answer;
4396
+ }
4397
+ return askRequired(rl, label);
4398
+ }
4399
+ async function askYesNo(rl, label, defaultValue) {
4400
+ const suffix = defaultValue ? "[Y/n]" : "[y/N]";
4401
+ const answer = normalizeInput(await rl.question(`${label} ${suffix}: `)).toLowerCase();
4402
+ if (answer.length === 0) {
4403
+ return defaultValue;
4404
+ }
4405
+ if (answer === "y" || answer === "yes") {
4406
+ return true;
4407
+ }
4408
+ if (answer === "n" || answer === "no") {
4409
+ return false;
4410
+ }
4411
+ return askYesNo(rl, label, defaultValue);
4412
+ }
4413
+ function readlinePrompts(rl) {
4414
+ return {
4415
+ askWithDefault: (label, defaultValue) => askWithDefault(rl, label, defaultValue),
4416
+ askRequired: (label) => askRequired(rl, label),
4417
+ askYesNo: (label, defaultValue) => askYesNo(rl, label, defaultValue)
4418
+ };
4419
+ }
4420
+ function writeSetupConfig(path, options) {
4421
+ try {
4422
+ writeFileSync(path, formatSetupConfig(options), { encoding: "utf8", mode: CONFIG_FILE_MODE });
4423
+ chmodSync(path, CONFIG_FILE_MODE);
4424
+ } catch (err) {
4425
+ const reason = err instanceof Error ? err.message : String(err);
4426
+ throw new SetupError(`failed to write ${path}: ${reason}`, { cause: err });
4427
+ }
4428
+ }
4429
+ function shellQuote(value) {
4430
+ return `'${value.replaceAll("'", "'\\''")}'`;
4431
+ }
4432
+ function unique(values) {
4433
+ return [...new Set(values.filter((value) => value.length > 0))];
4434
+ }
4435
+ function buildCronPath(options) {
4436
+ return unique([dirname(options.npxPath), dirname(options.nodePath), ...DEFAULT_CRON_PATHS]).join(":");
4437
+ }
4438
+ function buildCronBlock(options) {
4439
+ const path = buildCronPath({ npxPath: options.npxPath, nodePath: options.nodePath });
4440
+ const command = [
4441
+ `PATH=${shellQuote(path)}`,
4442
+ shellQuote(options.npxPath),
4443
+ "-y",
4444
+ shellQuote(options.packageName),
4445
+ "sync",
4446
+ ">>",
4447
+ shellQuote(options.logPath),
4448
+ "2>&1"
4449
+ ].join(" ");
4450
+ return [CRON_START_MARKER, `${options.minute} * * * * ${command}`, CRON_END_MARKER].join("\n");
4451
+ }
4452
+ function escapeRegex(value) {
4453
+ return value.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&");
4454
+ }
4455
+ function replaceManagedCronBlock(existingCrontab, managedBlock) {
4456
+ const blockPattern = new RegExp(
4457
+ `(?:^|\\n)${escapeRegex(CRON_START_MARKER)}\\n[\\s\\S]*?\\n${escapeRegex(CRON_END_MARKER)}\\n?`,
4458
+ "u"
4459
+ );
4460
+ const withoutManagedBlock = existingCrontab.replace(blockPattern, "\n").trimEnd();
4461
+ return withoutManagedBlock.length > 0 ? `${withoutManagedBlock}
4462
+ ${managedBlock}
4463
+ ` : `${managedBlock}
4464
+ `;
4465
+ }
4466
+ function findNpxPath(commandRunner) {
4467
+ const result = commandRunner("/bin/sh", ["-lc", "command -v npx"]);
4468
+ const npxPath = result.stdout.trim().split(LINE_SPLIT_PATTERN)[0] ?? "";
4469
+ if (result.status === 0 && npxPath.length > 0) {
4470
+ return npxPath;
4471
+ }
4472
+ const reason = result.error?.message ?? result.stderr.trim() ?? "npx was not found";
4473
+ throw new SetupError(`failed to set up cron: ${reason}`);
4474
+ }
4475
+ function listCrontab(commandRunner) {
4476
+ const result = commandRunner("crontab", ["-l"]);
4477
+ if (result.status === 0) {
4478
+ return result.stdout;
4479
+ }
4480
+ if (result.stderr.toLowerCase().includes("no crontab")) {
4481
+ return "";
4482
+ }
4483
+ const reason = result.error?.message ?? result.stderr.trim() ?? "crontab -l failed";
4484
+ throw new SetupError(`failed to read existing crontab: ${reason}`);
4485
+ }
4486
+ function installCronBlock(commandRunner, managedBlock) {
4487
+ const existingCrontab = listCrontab(commandRunner);
4488
+ const updatedCrontab = replaceManagedCronBlock(existingCrontab, managedBlock);
4489
+ const result = commandRunner("crontab", ["-"], updatedCrontab);
4490
+ if (result.status !== 0) {
4491
+ const reason = result.error?.message ?? result.stderr.trim() ?? "crontab update failed";
4492
+ throw new SetupError(`failed to install cron entry: ${reason}`);
4493
+ }
4494
+ }
4495
+ function readExistingConfig(homeDir, hostName) {
4496
+ const path = userConfigPath(homeDir);
4497
+ if (!existsSync(path)) {
4498
+ return { serverUrl: DEFAULT_SERVER_URL, device: hostName };
4499
+ }
4500
+ try {
4501
+ const config = loadCliConfig({
4502
+ configFileText: readFileSync2(path, "utf8"),
4503
+ configPath: path,
4504
+ env: {},
4505
+ homeDir,
4506
+ hostName
4507
+ });
4508
+ return { serverUrl: config.serverUrl, device: config.device ?? hostName };
4509
+ } catch (err) {
4510
+ if (err instanceof CliConfigError) {
4511
+ throw err;
4512
+ }
4513
+ const reason = err instanceof Error ? err.message : String(err);
4514
+ throw new SetupError(`failed to read existing ${path}: ${reason}`, { cause: err });
4515
+ }
4516
+ }
4517
+ function resolveApiValue(apiFlag2, prompts, defaultServerUrl) {
4518
+ return apiFlag2 === void 0 ? prompts.askWithDefault("Server URL", defaultServerUrl) : Promise.resolve(normalizeInput(apiFlag2));
4519
+ }
4520
+ function installSetupCron(options) {
4521
+ const npxPath = findNpxPath(options.commandRunner);
4522
+ const minute = options.randomMinute?.() ?? randomInt(0, 60);
4523
+ const logPath = join2(options.homeDir, ".oopst-sync.log");
4524
+ const managedBlock = buildCronBlock({
4525
+ minute,
4526
+ packageName: options.packageName,
4527
+ npxPath,
4528
+ nodePath: options.nodePath,
4529
+ logPath
4530
+ });
4531
+ installCronBlock(options.commandRunner, managedBlock);
4532
+ return { minute, npxPath };
4533
+ }
4534
+ async function runSetup(options = {}) {
4535
+ const homeDir = options.homeDir ?? readHomedir2();
4536
+ const hostName = options.hostName ?? readHostname2();
4537
+ const input = options.input ?? process2.stdin;
4538
+ const output = options.output ?? process2.stdout;
4539
+ const packageName = options.packageName ?? DEFAULT_PACKAGE_NAME;
4540
+ const commandRunner = options.commandRunner ?? defaultCommandRunner;
4541
+ const nodePath = options.nodePath ?? process2.execPath;
4542
+ const configPath = userConfigPath(homeDir);
4543
+ const defaults = readExistingConfig(homeDir, hostName);
4544
+ const apiFlag2 = options.api ?? options.server;
4545
+ const rl = options.prompts === void 0 ? createInterface({ input, output }) : void 0;
4546
+ const prompts = options.prompts ?? readlinePrompts(rl);
4547
+ try {
4548
+ const api = await resolveApiValue(apiFlag2, prompts, defaults.serverUrl);
4549
+ if (api.length === 0) {
4550
+ throw new SetupError("error: --api must be a non-empty string", { exitCode: EXIT.invalidArguments });
4551
+ }
4552
+ const device = await prompts.askWithDefault("Device name", defaults.device ?? hostName);
4553
+ const token = await prompts.askRequired("Token");
4554
+ const shouldInstallCron = await prompts.askYesNo("Setup cron?", false);
4555
+ writeSetupConfig(configPath, { api, token, device });
4556
+ writeLine(output, `Wrote ${configPath}`);
4557
+ if (!shouldInstallCron) {
4558
+ writeLine(output, "Cron setup skipped.");
4559
+ return { exitCode: EXIT.success, configPath, cronInstalled: false };
4560
+ }
4561
+ const { minute, npxPath } = installSetupCron({
4562
+ commandRunner,
4563
+ randomMinute: options.randomMinute,
4564
+ packageName,
4565
+ nodePath,
4566
+ homeDir
4567
+ });
4568
+ writeLine(output, `Installed cron entry for minute ${minute} of every hour.`);
4569
+ writeLine(output, `Cron uses ${npxPath} with an explicit PATH so it does not depend on your login shell.`);
4570
+ return { exitCode: EXIT.success, configPath, cronInstalled: true, cronMinute: minute };
4571
+ } finally {
4572
+ rl?.close();
4573
+ }
4574
+ }
6194
4575
 
6195
- // ../../packages/parsers/src/index.ts
6196
- init_esm_shims();
4576
+ // src/sync/parser-factory.ts
4577
+ import { dirname as dirname3, isAbsolute as isAbsolute3, join as join7, matchesGlob, relative } from "path";
6197
4578
 
6198
4579
  // ../../packages/parsers/src/claude/index.ts
6199
- init_esm_shims();
6200
4580
  import { stat as stat2 } from "fs/promises";
6201
- import { basename, dirname } from "path";
4581
+ import { basename, dirname as dirname2 } from "path";
6202
4582
 
6203
4583
  // ../../packages/parsers/src/config.ts
6204
- init_esm_shims();
6205
4584
  import { homedir } from "os";
6206
- import { isAbsolute as isAbsolute2, join as join2 } from "path";
4585
+ import { isAbsolute as isAbsolute2, join as join3 } from "path";
6207
4586
  import process3 from "process";
6208
- import { Config as Config2, ConfigProvider as ConfigProvider2, Effect as Effect17, Schema as Schema15 } from "effect";
4587
+ import { Config as Config2, ConfigProvider as ConfigProvider2, Effect as Effect11, Schema as Schema14 } from "effect";
6209
4588
  var runtimeEnv2 = process3["env"];
6210
- var RawParserEnvSchema = Schema15.Struct({
4589
+ var RawParserEnvSchema = Schema14.Struct({
6211
4590
  // biome-ignore lint/style/useNamingConvention: ENV vars are SCREAMING_SNAKE_CASE by convention
6212
- CLAUDE_CONFIG_DIR: Schema15.optional(Schema15.Trim),
4591
+ CLAUDE_CONFIG_DIR: Schema14.optional(Schema14.Trim),
6213
4592
  // biome-ignore lint/style/useNamingConvention: ENV vars are SCREAMING_SNAKE_CASE by convention
6214
- HERMES_CODING_AGENT_DIR: Schema15.optional(Schema15.Trim),
4593
+ HERMES_CODING_AGENT_DIR: Schema14.optional(Schema14.Trim),
6215
4594
  // biome-ignore lint/style/useNamingConvention: ENV vars are SCREAMING_SNAKE_CASE by convention
6216
- HERMES_CODING_AGENT_SESSION_DIR: Schema15.optional(Schema15.Trim),
4595
+ HERMES_CODING_AGENT_SESSION_DIR: Schema14.optional(Schema14.Trim),
6217
4596
  // biome-ignore lint/style/useNamingConvention: ENV vars are SCREAMING_SNAKE_CASE by convention
6218
- OPENCODE_DATA_DIR: Schema15.optional(Schema15.Trim),
4597
+ OPENCODE_DATA_DIR: Schema14.optional(Schema14.Trim),
6219
4598
  // biome-ignore lint/style/useNamingConvention: ENV vars are SCREAMING_SNAKE_CASE by convention
6220
- OPENCODE_DB: Schema15.optional(Schema15.Trim),
4599
+ OPENCODE_DB: Schema14.optional(Schema14.Trim),
6221
4600
  // biome-ignore lint/style/useNamingConvention: ENV vars are SCREAMING_SNAKE_CASE by convention
6222
- PI_CODING_AGENT_DIR: Schema15.optional(Schema15.Trim),
4601
+ PI_CODING_AGENT_DIR: Schema14.optional(Schema14.Trim),
6223
4602
  // biome-ignore lint/style/useNamingConvention: ENV vars are SCREAMING_SNAKE_CASE by convention
6224
- PI_CODING_AGENT_SESSION_DIR: Schema15.optional(Schema15.Trim)
4603
+ PI_CODING_AGENT_SESSION_DIR: Schema14.optional(Schema14.Trim)
6225
4604
  });
6226
4605
  var parserEnvConfig = Config2.schema(RawParserEnvSchema);
6227
4606
  var emptyToUndefined = (value) => value === void 0 || value.length === 0 ? void 0 : value;
@@ -6237,31 +4616,31 @@ var toParserConfig = (raw) => ({
6237
4616
  });
6238
4617
  function loadParserConfigEffect(env = runtimeEnv2) {
6239
4618
  const provider = ConfigProvider2.fromEnv({ env: toConfigEnv2(env) });
6240
- return parserEnvConfig.parse(provider).pipe(Effect17.map(toParserConfig));
4619
+ return parserEnvConfig.parse(provider).pipe(Effect11.map(toParserConfig));
6241
4620
  }
6242
4621
  function loadParserConfig(env = runtimeEnv2) {
6243
- return Effect17.runSync(loadParserConfigEffect(env));
4622
+ return Effect11.runSync(loadParserConfigEffect(env));
6244
4623
  }
6245
4624
  function readParserHomeDir() {
6246
4625
  return homedir();
6247
4626
  }
6248
4627
  function resolveCodexSessionsRoot(homeDir = readParserHomeDir()) {
6249
- return join2(homeDir, ".codex", "sessions");
4628
+ return join3(homeDir, ".codex", "sessions");
6250
4629
  }
6251
4630
  function resolveCodexArchivedRoot(homeDir = readParserHomeDir()) {
6252
- return join2(homeDir, ".codex", "archived_sessions");
4631
+ return join3(homeDir, ".codex", "archived_sessions");
6253
4632
  }
6254
4633
  function resolveClaudeRoot(config = loadParserConfig(), homeDir = readParserHomeDir()) {
6255
- return config.claudeConfigDir === void 0 ? join2(homeDir, ".claude", "projects") : join2(config.claudeConfigDir, "projects");
4634
+ return config.claudeConfigDir === void 0 ? join3(homeDir, ".claude", "projects") : join3(config.claudeConfigDir, "projects");
6256
4635
  }
6257
4636
  function resolvePiRoot(config = loadParserConfig(), homeDir = readParserHomeDir()) {
6258
- return config.piSessionDir ?? join2(config.piAgentDir ?? join2(homeDir, ".pi", "agent"), "sessions");
4637
+ return config.piSessionDir ?? join3(config.piAgentDir ?? join3(homeDir, ".pi", "agent"), "sessions");
6259
4638
  }
6260
4639
  function resolveHermesRoot(config = loadParserConfig(), homeDir = readParserHomeDir()) {
6261
- return config.hermesSessionDir ?? config.hermesAgentDir ?? join2(homeDir, ".hermes");
4640
+ return config.hermesSessionDir ?? config.hermesAgentDir ?? join3(homeDir, ".hermes");
6262
4641
  }
6263
4642
  function resolveOpenCodeDataRoot(config = loadParserConfig(), homeDir = readParserHomeDir()) {
6264
- return config.openCodeDataDir ?? join2(homeDir, ".local", "share", "opencode");
4643
+ return config.openCodeDataDir ?? join3(homeDir, ".local", "share", "opencode");
6265
4644
  }
6266
4645
  function resolveOpenCodeRoot(config = loadParserConfig(), homeDir = readParserHomeDir()) {
6267
4646
  const dataRoot = resolveOpenCodeDataRoot(config, homeDir);
@@ -6269,11 +4648,10 @@ function resolveOpenCodeRoot(config = loadParserConfig(), homeDir = readParserHo
6269
4648
  if (dbPath === void 0 || dbPath === ":memory:") {
6270
4649
  return dbPath ?? dataRoot;
6271
4650
  }
6272
- return isAbsolute2(dbPath) ? dbPath : join2(dataRoot, dbPath);
4651
+ return isAbsolute2(dbPath) ? dbPath : join3(dataRoot, dbPath);
6273
4652
  }
6274
4653
 
6275
4654
  // ../../packages/parsers/src/types.ts
6276
- init_esm_shims();
6277
4655
  import process4 from "process";
6278
4656
  function formatLogMeta(meta) {
6279
4657
  return JSON.stringify(meta);
@@ -6291,15 +4669,13 @@ var consoleLogger = {
6291
4669
  };
6292
4670
 
6293
4671
  // ../../packages/parsers/src/walk.ts
6294
- init_esm_shims();
6295
- import { Effect as Effect19 } from "effect";
4672
+ import { Effect as Effect13 } from "effect";
6296
4673
 
6297
4674
  // ../../packages/parsers/src/effect/file-walker.ts
6298
- init_esm_shims();
6299
4675
  import { readdir, stat } from "fs/promises";
6300
- 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") {
4676
+ import { join as join4 } from "path";
4677
+ import { Context as Context5, Effect as Effect12, Layer as Layer6 } from "effect";
4678
+ var FileWalker = class extends Context5.Service()("@oopst/parsers/FileWalker") {
6303
4679
  };
6304
4680
  async function* walkJsonlFiles(root, cutoff) {
6305
4681
  let entries;
@@ -6309,7 +4685,7 @@ async function* walkJsonlFiles(root, cutoff) {
6309
4685
  return;
6310
4686
  }
6311
4687
  for (const entry of entries) {
6312
- const full = join3(root, String(entry.name));
4688
+ const full = join4(root, String(entry.name));
6313
4689
  if (entry.isDirectory()) {
6314
4690
  yield* walkJsonlFiles(full, cutoff);
6315
4691
  continue;
@@ -6332,34 +4708,31 @@ async function* walkJsonlFiles(root, cutoff) {
6332
4708
  }
6333
4709
  }
6334
4710
  var makeFileWalker = () => ({
6335
- walk: (root, cutoff) => Effect18.succeed(walkJsonlFiles(root, cutoff))
4711
+ walk: (root, cutoff) => Effect12.succeed(walkJsonlFiles(root, cutoff))
6336
4712
  });
6337
- var FileWalkerLive = Layer11.succeed(FileWalker, makeFileWalker());
4713
+ var FileWalkerLive = Layer6.succeed(FileWalker, makeFileWalker());
6338
4714
 
6339
4715
  // ../../packages/parsers/src/walk.ts
6340
4716
  function walkEffect(root, cutoff) {
6341
- return Effect19.gen(function* () {
4717
+ return Effect13.gen(function* () {
6342
4718
  const walker = yield* FileWalker;
6343
4719
  return yield* walker.walk(root, cutoff);
6344
4720
  });
6345
4721
  }
6346
4722
  async function* walk(root, cutoff) {
6347
- const iterable = await walkEffect(root, cutoff).pipe(Effect19.provide(FileWalkerLive), Effect19.runPromise);
4723
+ const iterable = await walkEffect(root, cutoff).pipe(Effect13.provide(FileWalkerLive), Effect13.runPromise);
6348
4724
  yield* iterable;
6349
4725
  }
6350
4726
 
6351
4727
  // ../../packages/parsers/src/claude/bucketize.ts
6352
- init_esm_shims();
6353
4728
  import { createReadStream as createReadStream2 } from "fs";
6354
- import { createInterface as createInterface2 } from "readline";
4729
+ import { createInterface as createInterface3 } from "readline";
6355
4730
 
6356
4731
  // ../../packages/parsers/src/codex/bucketize.ts
6357
- init_esm_shims();
6358
4732
  import { createReadStream } from "fs";
6359
- import { createInterface } from "readline";
4733
+ import { createInterface as createInterface2 } from "readline";
6360
4734
 
6361
4735
  // ../../packages/parsers/src/codex/events.ts
6362
- init_esm_shims();
6363
4736
  function isObject(value) {
6364
4737
  return typeof value === "object" && value !== null && !Array.isArray(value);
6365
4738
  }
@@ -6483,18 +4856,18 @@ function startOfUtcHour(d) {
6483
4856
  function key2(hourUtc, model) {
6484
4857
  return `${hourUtc.toISOString()}|${model}`;
6485
4858
  }
6486
- function shouldExcludePath(path2, excludePath) {
6487
- return path2 !== void 0 && excludePath?.(path2) === true;
4859
+ function shouldExcludePath(path, excludePath) {
4860
+ return path !== void 0 && excludePath?.(path) === true;
6488
4861
  }
6489
- async function* bucketizeCodexFile(path2, logger, options = {}) {
4862
+ async function* bucketizeCodexFile(path, logger, options = {}) {
6490
4863
  const buckets = /* @__PURE__ */ new Map();
6491
4864
  let currentModel;
6492
4865
  let sawTurnContext = false;
6493
4866
  let lineNo = 0;
6494
4867
  let sessionStartedAt;
6495
4868
  let sessionLastSeenAt;
6496
- const stream = createReadStream(path2, { encoding: "utf8" });
6497
- const rl = createInterface({ input: stream, crlfDelay: Number.POSITIVE_INFINITY });
4869
+ const stream = createReadStream(path, { encoding: "utf8" });
4870
+ const rl = createInterface2({ input: stream, crlfDelay: Number.POSITIVE_INFINITY });
6498
4871
  try {
6499
4872
  for await (const raw of rl) {
6500
4873
  lineNo += 1;
@@ -6506,7 +4879,7 @@ async function* bucketizeCodexFile(path2, logger, options = {}) {
6506
4879
  try {
6507
4880
  parsed = JSON.parse(trimmed);
6508
4881
  } catch {
6509
- logger.warn("malformed jsonl line", { path: path2, line: lineNo });
4882
+ logger.warn("malformed jsonl line", { path, line: lineNo });
6510
4883
  continue;
6511
4884
  }
6512
4885
  if (isCodexSessionMetaEvent(parsed)) {
@@ -6580,7 +4953,7 @@ async function* bucketizeCodexFile(path2, logger, options = {}) {
6580
4953
  if (sessionStartedAt === void 0 || sessionLastSeenAt === void 0) {
6581
4954
  return;
6582
4955
  }
6583
- const sessionIds = /* @__PURE__ */ new Set([path2]);
4956
+ const sessionIds = /* @__PURE__ */ new Set([path]);
6584
4957
  for (const acc of buckets.values()) {
6585
4958
  yield {
6586
4959
  harness: "codex",
@@ -6598,7 +4971,6 @@ async function* bucketizeCodexFile(path2, logger, options = {}) {
6598
4971
  }
6599
4972
 
6600
4973
  // ../../packages/parsers/src/claude/events.ts
6601
- init_esm_shims();
6602
4974
  function isObject2(value) {
6603
4975
  return typeof value === "object" && value !== null && !Array.isArray(value);
6604
4976
  }
@@ -6654,14 +5026,14 @@ function isClaudeAssistantEvent(value) {
6654
5026
  function key3(hourUtc, model) {
6655
5027
  return `${hourUtc.toISOString()}|${model}`;
6656
5028
  }
6657
- async function* bucketizeClaudeFile(path2, logger, options = {}) {
5029
+ async function* bucketizeClaudeFile(path, logger, options = {}) {
6658
5030
  const buckets = /* @__PURE__ */ new Map();
6659
5031
  const seenTuples = options.seenTuples ?? /* @__PURE__ */ new Set();
6660
5032
  let lineNo = 0;
6661
5033
  let sessionStartedAt;
6662
5034
  let sessionLastSeenAt;
6663
- const stream = createReadStream2(path2, { encoding: "utf8" });
6664
- const rl = createInterface2({ input: stream, crlfDelay: Number.POSITIVE_INFINITY });
5035
+ const stream = createReadStream2(path, { encoding: "utf8" });
5036
+ const rl = createInterface3({ input: stream, crlfDelay: Number.POSITIVE_INFINITY });
6665
5037
  try {
6666
5038
  for await (const raw of rl) {
6667
5039
  lineNo += 1;
@@ -6673,7 +5045,7 @@ async function* bucketizeClaudeFile(path2, logger, options = {}) {
6673
5045
  try {
6674
5046
  parsed = JSON.parse(trimmed);
6675
5047
  } catch {
6676
- logger.warn("malformed jsonl line", { path: path2, line: lineNo });
5048
+ logger.warn("malformed jsonl line", { path, line: lineNo });
6677
5049
  continue;
6678
5050
  }
6679
5051
  if (!isClaudeAssistantEvent(parsed)) {
@@ -6735,7 +5107,7 @@ async function* bucketizeClaudeFile(path2, logger, options = {}) {
6735
5107
  if (sessionStartedAt === void 0 || sessionLastSeenAt === void 0) {
6736
5108
  return;
6737
5109
  }
6738
- const sessionIds = /* @__PURE__ */ new Set([options.sessionId ?? path2]);
5110
+ const sessionIds = /* @__PURE__ */ new Set([options.sessionId ?? path]);
6739
5111
  for (const acc of buckets.values()) {
6740
5112
  yield {
6741
5113
  harness: "claude_code",
@@ -6753,19 +5125,19 @@ async function* bucketizeClaudeFile(path2, logger, options = {}) {
6753
5125
  }
6754
5126
 
6755
5127
  // ../../packages/parsers/src/claude/index.ts
6756
- async function isFile(path2) {
5128
+ async function isFile(path) {
6757
5129
  try {
6758
- return (await stat2(path2)).isFile();
5130
+ return (await stat2(path)).isFile();
6759
5131
  } catch {
6760
5132
  return false;
6761
5133
  }
6762
5134
  }
6763
- function sourceSessionId(path2) {
6764
- const fileDir = dirname(path2);
5135
+ function sourceSessionId(path) {
5136
+ const fileDir = dirname2(path);
6765
5137
  if (basename(fileDir) !== "subagents") {
6766
- return path2;
5138
+ return path;
6767
5139
  }
6768
- const sessionDir = dirname(fileDir);
5140
+ const sessionDir = dirname2(fileDir);
6769
5141
  return `${sessionDir}.jsonl`;
6770
5142
  }
6771
5143
  async function* parseClaude(opts) {
@@ -6792,12 +5164,11 @@ async function* parseClaude(opts) {
6792
5164
  }
6793
5165
 
6794
5166
  // ../../packages/parsers/src/codex/index.ts
6795
- init_esm_shims();
6796
5167
  import { stat as stat3 } from "fs/promises";
6797
- import { Effect as Effect20 } from "effect";
6798
- async function isFile2(path2) {
5168
+ import { Effect as Effect14 } from "effect";
5169
+ async function isFile2(path) {
6799
5170
  try {
6800
- return (await stat3(path2)).isFile();
5171
+ return (await stat3(path)).isFile();
6801
5172
  } catch {
6802
5173
  return false;
6803
5174
  }
@@ -6805,8 +5176,8 @@ async function isFile2(path2) {
6805
5176
  function parseCodexEffect(opts) {
6806
5177
  const logger = opts.logger ?? consoleLogger;
6807
5178
  const root = opts.root ?? resolveCodexSessionsRoot();
6808
- return Effect20.gen(function* () {
6809
- if (yield* Effect20.tryPromise({ try: () => isFile2(root), catch: (error) => error })) {
5179
+ return Effect14.gen(function* () {
5180
+ if (yield* Effect14.tryPromise({ try: () => isFile2(root), catch: (error) => error })) {
6810
5181
  return bucketizeCodexFile(root, logger, { excludePath: opts.excludePath });
6811
5182
  }
6812
5183
  const roots = [root];
@@ -6830,21 +5201,18 @@ async function* bucketizeCodexSources(sources, logger, options) {
6830
5201
  }
6831
5202
  }
6832
5203
  async function* parseCodex(opts) {
6833
- const iterable = await parseCodexEffect(opts).pipe(Effect20.provide(FileWalkerLive), Effect20.runPromise);
5204
+ const iterable = await parseCodexEffect(opts).pipe(Effect14.provide(FileWalkerLive), Effect14.runPromise);
6834
5205
  yield* iterable;
6835
5206
  }
6836
5207
 
6837
5208
  // ../../packages/parsers/src/opencode/index.ts
6838
- init_esm_shims();
6839
5209
  import { readdir as readdir2, stat as stat4 } from "fs/promises";
6840
- import { basename as basename2, join as join4 } from "path";
5210
+ import { basename as basename2, join as join5 } from "path";
6841
5211
 
6842
5212
  // ../../packages/parsers/src/opencode/bucketize.ts
6843
- init_esm_shims();
6844
5213
  import { readFile } from "fs/promises";
6845
5214
 
6846
5215
  // ../../packages/parsers/src/opencode/events.ts
6847
- init_esm_shims();
6848
5216
  function isObject3(value) {
6849
5217
  return typeof value === "object" && value !== null && !Array.isArray(value);
6850
5218
  }
@@ -7044,7 +5412,7 @@ function addUsage(accumulators, usage) {
7044
5412
  }
7045
5413
  function shouldExcludeUsage(usage, sessionPaths, excludePath) {
7046
5414
  const paths = sessionPaths.get(usage.sessionId);
7047
- return paths?.some((path2) => excludePath?.(path2) === true) === true;
5415
+ return paths?.some((path) => excludePath?.(path) === true) === true;
7048
5416
  }
7049
5417
  function* finalizedBuckets(accumulators) {
7050
5418
  for (const acc of accumulators.values()) {
@@ -7113,12 +5481,12 @@ function readSessionPaths(db) {
7113
5481
  }
7114
5482
  return paths;
7115
5483
  }
7116
- async function* bucketizeOpenCodeDatabase(path2, cutoff, logger, excludePath) {
5484
+ async function* bucketizeOpenCodeDatabase(path, cutoff, logger, excludePath) {
7117
5485
  const accumulators = /* @__PURE__ */ new Map();
7118
5486
  const DatabaseSync = await loadDatabaseSync();
7119
5487
  let db;
7120
5488
  try {
7121
- db = new DatabaseSync(path2, { readOnly: true, timeout: 1e3 });
5489
+ db = new DatabaseSync(path, { readOnly: true, timeout: 1e3 });
7122
5490
  const sessionPaths = readSessionPaths(db);
7123
5491
  for (const row of readSessionMessageRows(db, cutoff)) {
7124
5492
  const sessionId = typeof row.sessionId === "string" ? row.sessionId : void 0;
@@ -7127,7 +5495,7 @@ async function* bucketizeOpenCodeDatabase(path2, cutoff, logger, excludePath) {
7127
5495
  try {
7128
5496
  parsed = parseJson(row.data);
7129
5497
  } catch {
7130
- logger.warn("malformed opencode sqlite message", { path: path2 });
5498
+ logger.warn("malformed opencode sqlite message", { path });
7131
5499
  continue;
7132
5500
  }
7133
5501
  const usage = pickOpenCodeUsage(parsed, sessionId, fallbackTimestampMs);
@@ -7137,19 +5505,19 @@ async function* bucketizeOpenCodeDatabase(path2, cutoff, logger, excludePath) {
7137
5505
  }
7138
5506
  } catch (err) {
7139
5507
  if (!isMissingTableError(err)) {
7140
- logger.warn("failed to parse opencode sqlite database", { path: path2 });
5508
+ logger.warn("failed to parse opencode sqlite database", { path });
7141
5509
  }
7142
5510
  } finally {
7143
5511
  db?.close();
7144
5512
  }
7145
5513
  yield* finalizedBuckets(accumulators);
7146
5514
  }
7147
- async function* bucketizeOpenCodeJsonFile(path2, logger) {
5515
+ async function* bucketizeOpenCodeJsonFile(path, logger) {
7148
5516
  let parsed;
7149
5517
  try {
7150
- parsed = JSON.parse(await readFile(path2, "utf8"));
5518
+ parsed = JSON.parse(await readFile(path, "utf8"));
7151
5519
  } catch {
7152
- logger.warn("malformed opencode json file", { path: path2 });
5520
+ logger.warn("malformed opencode json file", { path });
7153
5521
  return;
7154
5522
  }
7155
5523
  const usage = pickOpenCodeUsage(parsed);
@@ -7163,9 +5531,9 @@ async function* bucketizeOpenCodeJsonFile(path2, logger) {
7163
5531
 
7164
5532
  // ../../packages/parsers/src/opencode/index.ts
7165
5533
  var OPENCODE_DB_FILE_PATTERN = /^opencode(?:-[^/]+)?\.db$/u;
7166
- async function pathKind(path2) {
5534
+ async function pathKind(path) {
7167
5535
  try {
7168
- const s = await stat4(path2);
5536
+ const s = await stat4(path);
7169
5537
  if (s.isFile()) {
7170
5538
  return "file";
7171
5539
  }
@@ -7184,10 +5552,10 @@ async function listOpenCodeDatabases(root) {
7184
5552
  } catch {
7185
5553
  return [];
7186
5554
  }
7187
- return entries.filter((entry) => entry.isFile() && OPENCODE_DB_FILE_PATTERN.test(String(entry.name))).map((entry) => join4(root, String(entry.name)));
5555
+ return entries.filter((entry) => entry.isFile() && OPENCODE_DB_FILE_PATTERN.test(String(entry.name))).map((entry) => join5(root, String(entry.name)));
7188
5556
  }
7189
5557
  async function listProjectLegacyRoots(root) {
7190
- const projectRoot = join4(root, "project");
5558
+ const projectRoot = join5(root, "project");
7191
5559
  let entries;
7192
5560
  try {
7193
5561
  entries = await readdir2(projectRoot, { withFileTypes: true });
@@ -7195,14 +5563,14 @@ async function listProjectLegacyRoots(root) {
7195
5563
  return [];
7196
5564
  }
7197
5565
  return entries.filter((entry) => entry.isDirectory()).flatMap((entry) => [
7198
- join4(projectRoot, String(entry.name), "storage", "message"),
7199
- join4(projectRoot, String(entry.name), "storage", "session", "message")
5566
+ join5(projectRoot, String(entry.name), "storage", "message"),
5567
+ join5(projectRoot, String(entry.name), "storage", "session", "message")
7200
5568
  ]);
7201
5569
  }
7202
5570
  async function legacyRoots(root) {
7203
5571
  return [
7204
- join4(root, "storage", "message"),
7205
- join4(root, "storage", "session", "message"),
5572
+ join5(root, "storage", "message"),
5573
+ join5(root, "storage", "session", "message"),
7206
5574
  ...await listProjectLegacyRoots(root)
7207
5575
  ];
7208
5576
  }
@@ -7214,7 +5582,7 @@ async function* walkJson(root, cutoff) {
7214
5582
  return;
7215
5583
  }
7216
5584
  for (const entry of entries) {
7217
- const full = join4(root, String(entry.name));
5585
+ const full = join5(root, String(entry.name));
7218
5586
  if (entry.isDirectory()) {
7219
5587
  yield* walkJson(full, cutoff);
7220
5588
  continue;
@@ -7263,17 +5631,14 @@ async function* parseOpenCode(opts) {
7263
5631
  }
7264
5632
 
7265
5633
  // ../../packages/parsers/src/pi/index.ts
7266
- init_esm_shims();
7267
5634
  import { stat as stat5 } from "fs/promises";
7268
- import { basename as basename3, join as join5 } from "path";
5635
+ import { basename as basename3, join as join6 } from "path";
7269
5636
 
7270
5637
  // ../../packages/parsers/src/pi/bucketize.ts
7271
- init_esm_shims();
7272
5638
  import { createReadStream as createReadStream3 } from "fs";
7273
- import { createInterface as createInterface3 } from "readline";
5639
+ import { createInterface as createInterface4 } from "readline";
7274
5640
 
7275
5641
  // ../../packages/parsers/src/pi/events.ts
7276
- init_esm_shims();
7277
5642
  function isObject4(value) {
7278
5643
  return typeof value === "object" && value !== null && !Array.isArray(value);
7279
5644
  }
@@ -7440,14 +5805,14 @@ function hermesRowToBucket(row, excludePath) {
7440
5805
  sessionLastSeenAt: new Date(lastSeenAtMs)
7441
5806
  };
7442
5807
  }
7443
- async function* bucketizePiStyleFile(path2, harness, logger, options = {}) {
5808
+ async function* bucketizePiStyleFile(path, harness, logger, options = {}) {
7444
5809
  const buckets = /* @__PURE__ */ new Map();
7445
5810
  const seenMessageIds = options.seenMessageIds ?? /* @__PURE__ */ new Set();
7446
5811
  let lineNo = 0;
7447
5812
  let sessionStartedAt;
7448
5813
  let sessionLastSeenAt;
7449
- const stream = createReadStream3(path2, { encoding: "utf8" });
7450
- const rl = createInterface3({ input: stream, crlfDelay: Number.POSITIVE_INFINITY });
5814
+ const stream = createReadStream3(path, { encoding: "utf8" });
5815
+ const rl = createInterface4({ input: stream, crlfDelay: Number.POSITIVE_INFINITY });
7451
5816
  try {
7452
5817
  for await (const raw of rl) {
7453
5818
  lineNo += 1;
@@ -7459,7 +5824,7 @@ async function* bucketizePiStyleFile(path2, harness, logger, options = {}) {
7459
5824
  try {
7460
5825
  parsed = JSON.parse(trimmed);
7461
5826
  } catch {
7462
- logger.warn("malformed jsonl line", { path: path2, line: lineNo });
5827
+ logger.warn("malformed jsonl line", { path, line: lineNo });
7463
5828
  continue;
7464
5829
  }
7465
5830
  if (isPiSessionEntry(parsed)) {
@@ -7529,7 +5894,7 @@ async function* bucketizePiStyleFile(path2, harness, logger, options = {}) {
7529
5894
  if (sessionStartedAt === void 0 || sessionLastSeenAt === void 0) {
7530
5895
  return;
7531
5896
  }
7532
- const sessionIds = /* @__PURE__ */ new Set([path2]);
5897
+ const sessionIds = /* @__PURE__ */ new Set([path]);
7533
5898
  for (const acc of buckets.values()) {
7534
5899
  yield {
7535
5900
  harness,
@@ -7545,11 +5910,11 @@ async function* bucketizePiStyleFile(path2, harness, logger, options = {}) {
7545
5910
  };
7546
5911
  }
7547
5912
  }
7548
- async function* bucketizeHermesDatabase(path2, cutoff, logger, excludePath) {
5913
+ async function* bucketizeHermesDatabase(path, cutoff, logger, excludePath) {
7549
5914
  const DatabaseSync = await loadDatabaseSync2();
7550
5915
  let db;
7551
5916
  try {
7552
- db = new DatabaseSync(path2, { readOnly: true, timeout: 1e3 });
5917
+ db = new DatabaseSync(path, { readOnly: true, timeout: 1e3 });
7553
5918
  for (const row of readHermesSessionRows(db, cutoff)) {
7554
5919
  const bucket = hermesRowToBucket(row, excludePath);
7555
5920
  if (bucket !== void 0) {
@@ -7557,16 +5922,16 @@ async function* bucketizeHermesDatabase(path2, cutoff, logger, excludePath) {
7557
5922
  }
7558
5923
  }
7559
5924
  } catch {
7560
- logger.warn("failed to parse hermes sqlite database", { path: path2 });
5925
+ logger.warn("failed to parse hermes sqlite database", { path });
7561
5926
  } finally {
7562
5927
  db?.close();
7563
5928
  }
7564
5929
  }
7565
5930
 
7566
5931
  // ../../packages/parsers/src/pi/index.ts
7567
- async function pathKind2(path2) {
5932
+ async function pathKind2(path) {
7568
5933
  try {
7569
- const s = await stat5(path2);
5934
+ const s = await stat5(path);
7570
5935
  if (s.isFile()) {
7571
5936
  return "file";
7572
5937
  }
@@ -7578,8 +5943,8 @@ async function pathKind2(path2) {
7578
5943
  return "missing";
7579
5944
  }
7580
5945
  }
7581
- async function isFile3(path2) {
7582
- return await pathKind2(path2) === "file";
5946
+ async function isFile3(path) {
5947
+ return await pathKind2(path) === "file";
7583
5948
  }
7584
5949
  async function* parsePiStyle(opts, harness, defaultRoot) {
7585
5950
  const logger = opts.logger ?? consoleLogger;
@@ -7614,12 +5979,12 @@ async function* parseHermes(opts) {
7614
5979
  yield* bucketizePiStyleFile(root, "hermes", logger, { excludePath: opts.excludePath });
7615
5980
  return;
7616
5981
  }
7617
- const stateDb = join5(root, "state.db");
5982
+ const stateDb = join6(root, "state.db");
7618
5983
  if (await isFile3(stateDb)) {
7619
5984
  yield* bucketizeHermesDatabase(stateDb, opts.cutoff, logger, opts.excludePath);
7620
5985
  return;
7621
5986
  }
7622
- const sessionsRoot2 = join5(root, "sessions");
5987
+ const sessionsRoot2 = join6(root, "sessions");
7623
5988
  if (await pathKind2(sessionsRoot2) === "directory") {
7624
5989
  const seenMessageIds2 = /* @__PURE__ */ new Set();
7625
5990
  for await (const file of walk(sessionsRoot2, opts.cutoff)) {
@@ -7630,7 +5995,7 @@ async function* parseHermes(opts) {
7630
5995
  }
7631
5996
  return;
7632
5997
  }
7633
- const agentSessionsRoot = join5(root, "agent", "sessions");
5998
+ const agentSessionsRoot = join6(root, "agent", "sessions");
7634
5999
  if (await pathKind2(agentSessionsRoot) === "directory") {
7635
6000
  const seenMessageIds2 = /* @__PURE__ */ new Set();
7636
6001
  for await (const file of walk(agentSessionsRoot, opts.cutoff)) {
@@ -7651,49 +6016,48 @@ async function* parseHermes(opts) {
7651
6016
  }
7652
6017
 
7653
6018
  // src/sync/parser-factory.ts
7654
- import { Effect as Effect22 } from "effect";
6019
+ import { Effect as Effect16 } from "effect";
7655
6020
 
7656
6021
  // src/services/parser-sources.ts
7657
- init_esm_shims();
7658
- import { existsSync, readdirSync, statSync } from "fs";
6022
+ import { existsSync as existsSync2, readdirSync, statSync } from "fs";
7659
6023
  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") {
6024
+ import { Context as Context6, Effect as Effect15, Layer as Layer7 } from "effect";
6025
+ var ParserSources = class extends Context6.Service()("@oopst/cli/ParserSources") {
7662
6026
  };
7663
6027
  function makeParserSources() {
7664
6028
  return {
7665
- homeDir: Effect21.sync(() => homedir2()),
7666
- cliEnv: Effect21.sync(() => readCliEnv()),
7667
- exists: (path2) => Effect21.sync(() => existsSync(path2)),
7668
- isFile: (path2) => Effect21.sync(() => {
6029
+ homeDir: Effect15.sync(() => homedir2()),
6030
+ cliEnv: Effect15.sync(() => readCliEnv()),
6031
+ exists: (path) => Effect15.sync(() => existsSync2(path)),
6032
+ isFile: (path) => Effect15.sync(() => {
7669
6033
  try {
7670
- return statSync(path2).isFile();
6034
+ return statSync(path).isFile();
7671
6035
  } catch {
7672
6036
  return false;
7673
6037
  }
7674
6038
  }),
7675
- readDir: (path2) => Effect21.sync(() => {
6039
+ readDir: (path) => Effect15.sync(() => {
7676
6040
  try {
7677
- return readdirSync(path2);
6041
+ return readdirSync(path);
7678
6042
  } catch {
7679
6043
  return [];
7680
6044
  }
7681
6045
  })
7682
6046
  };
7683
6047
  }
7684
- var ParserSourcesLive = Layer12.succeed(ParserSources, makeParserSources());
6048
+ var ParserSourcesLive = Layer7.succeed(ParserSources, makeParserSources());
7685
6049
 
7686
6050
  // src/sync/parser-factory.ts
7687
6051
  var OPENCODE_DB_FILE_PATTERN2 = /^opencode(?:-[^/]+)?\.db$/u;
7688
6052
  var GLOB_PATTERN = /[*?[\]{}]/u;
7689
6053
  function sessionsRoot(agentDir, sessionDir, fallbackAgentDir) {
7690
- return sessionDir ?? join6(agentDir ?? fallbackAgentDir, "sessions");
6054
+ return sessionDir ?? join7(agentDir ?? fallbackAgentDir, "sessions");
7691
6055
  }
7692
6056
  function hermesRoot(home, env) {
7693
- return env.hermesSessionDir ?? env.hermesAgentDir ?? join6(home, ".hermes");
6057
+ return env.hermesSessionDir ?? env.hermesAgentDir ?? join7(home, ".hermes");
7694
6058
  }
7695
6059
  function defaultOpenCodeDataRoot(home) {
7696
- return join6(home, ".local", "share", "opencode");
6060
+ return join7(home, ".local", "share", "opencode");
7697
6061
  }
7698
6062
  function openCodeRoot(home, env) {
7699
6063
  const dataRoot = env.opencodeDataDir ?? defaultOpenCodeDataRoot(home);
@@ -7701,14 +6065,14 @@ function openCodeRoot(home, env) {
7701
6065
  if (dbPath === void 0 || dbPath === ":memory:") {
7702
6066
  return dbPath ?? dataRoot;
7703
6067
  }
7704
- return isAbsolute3(dbPath) ? dbPath : join6(dataRoot, dbPath);
6068
+ return isAbsolute3(dbPath) ? dbPath : join7(dataRoot, dbPath);
7705
6069
  }
7706
6070
  function hasOpenCodeDatabaseEffect(root) {
7707
- return Effect22.gen(function* () {
6071
+ return Effect16.gen(function* () {
7708
6072
  const sources = yield* ParserSources;
7709
6073
  const entries = yield* sources.readDir(root);
7710
6074
  for (const entry of entries) {
7711
- if (OPENCODE_DB_FILE_PATTERN2.test(entry) && (yield* sources.isFile(join6(root, entry)))) {
6075
+ if (OPENCODE_DB_FILE_PATTERN2.test(entry) && (yield* sources.isFile(join7(root, entry)))) {
7712
6076
  return true;
7713
6077
  }
7714
6078
  }
@@ -7717,42 +6081,42 @@ function hasOpenCodeDatabaseEffect(root) {
7717
6081
  }
7718
6082
  function openCodeSourceExistsEffect(root) {
7719
6083
  if (root === ":memory:") {
7720
- return Effect22.succeed(false);
6084
+ return Effect16.succeed(false);
7721
6085
  }
7722
- return Effect22.gen(function* () {
6086
+ return Effect16.gen(function* () {
7723
6087
  const sources = yield* ParserSources;
7724
6088
  if (yield* sources.isFile(root)) {
7725
6089
  return true;
7726
6090
  }
7727
- return (yield* hasOpenCodeDatabaseEffect(root)) || (yield* sources.exists(join6(root, "storage", "message"))) || (yield* sources.exists(join6(root, "storage", "session", "message"))) || (yield* sources.exists(join6(root, "project")));
6091
+ return (yield* hasOpenCodeDatabaseEffect(root)) || (yield* sources.exists(join7(root, "storage", "message"))) || (yield* sources.exists(join7(root, "storage", "session", "message"))) || (yield* sources.exists(join7(root, "project")));
7728
6092
  });
7729
6093
  }
7730
6094
  function hermesSourceExistsEffect(root) {
7731
- return Effect22.gen(function* () {
6095
+ return Effect16.gen(function* () {
7732
6096
  const sources = yield* ParserSources;
7733
- 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")));
6097
+ return (yield* sources.isFile(root)) || (yield* sources.exists(join7(root, "state.db"))) || (yield* sources.exists(join7(root, "sessions"))) || (yield* sources.exists(join7(root, "agent", "sessions")));
7734
6098
  });
7735
6099
  }
7736
- function isPathInsideOrEqual(path2, parent) {
7737
- const rel = relative(parent, path2);
6100
+ function isPathInsideOrEqual(path, parent) {
6101
+ const rel = relative(parent, path);
7738
6102
  return rel === "" || !(rel.startsWith("..") || isAbsolute3(rel));
7739
6103
  }
7740
- function comparableLocalPath(path2, home) {
7741
- if (!(path2 === "~" || path2.startsWith("~/") || isAbsolute3(path2))) {
6104
+ function comparableLocalPath(path, home) {
6105
+ if (!(path === "~" || path.startsWith("~/") || isAbsolute3(path))) {
7742
6106
  return void 0;
7743
6107
  }
7744
- return normalizeConfigPath(path2, home);
6108
+ return normalizeConfigPath(path, home);
7745
6109
  }
7746
- function hasGlobPattern(path2) {
7747
- return GLOB_PATTERN.test(path2);
6110
+ function hasGlobPattern(path) {
6111
+ return GLOB_PATTERN.test(path);
7748
6112
  }
7749
- function matchesPathOrAncestorGlob(path2, pattern) {
7750
- let current = path2;
6113
+ function matchesPathOrAncestorGlob(path, pattern) {
6114
+ let current = path;
7751
6115
  for (; ; ) {
7752
6116
  if (matchesGlob(current, pattern)) {
7753
6117
  return true;
7754
6118
  }
7755
- const parent = dirname2(current);
6119
+ const parent = dirname3(current);
7756
6120
  if (parent === current) {
7757
6121
  return false;
7758
6122
  }
@@ -7760,15 +6124,15 @@ function matchesPathOrAncestorGlob(path2, pattern) {
7760
6124
  }
7761
6125
  }
7762
6126
  function createExcludeMatcher(options) {
7763
- const normalizedExclude = options.exclude.map((path2) => {
7764
- const normalizedPath = normalizeConfigPath(path2, options.home);
6127
+ const normalizedExclude = options.exclude.map((path) => {
6128
+ const normalizedPath = normalizeConfigPath(path, options.home);
7765
6129
  return {
7766
6130
  isGlob: hasGlobPattern(normalizedPath),
7767
6131
  path: normalizedPath
7768
6132
  };
7769
6133
  });
7770
- return (path2) => {
7771
- const comparable = comparableLocalPath(path2, options.home);
6134
+ return (path) => {
6135
+ const comparable = comparableLocalPath(path, options.home);
7772
6136
  if (comparable === void 0) {
7773
6137
  return false;
7774
6138
  }
@@ -7778,17 +6142,17 @@ function createExcludeMatcher(options) {
7778
6142
  };
7779
6143
  }
7780
6144
  function resolveParserSourcePlanEffect(options = {}) {
7781
- return Effect22.gen(function* () {
6145
+ return Effect16.gen(function* () {
7782
6146
  const sources = yield* ParserSources;
7783
6147
  const home = yield* sources.homeDir;
7784
6148
  const env = yield* sources.cliEnv;
7785
- const codexSessionsRoot = join6(home, ".codex", "sessions");
7786
- const codexArchivedRoot = join6(home, ".codex", "archived_sessions");
6149
+ const codexSessionsRoot = join7(home, ".codex", "sessions");
6150
+ const codexArchivedRoot = join7(home, ".codex", "archived_sessions");
7787
6151
  const codexExists = (yield* sources.exists(codexSessionsRoot)) || (yield* sources.exists(codexArchivedRoot));
7788
6152
  const envDir = env.claudeConfigDir;
7789
- const claudeRoot = envDir == null ? join6(home, ".claude", "projects") : join6(envDir, "projects");
6153
+ const claudeRoot = envDir == null ? join7(home, ".claude", "projects") : join7(envDir, "projects");
7790
6154
  const claudeExists = yield* sources.exists(claudeRoot);
7791
- const piRoot = sessionsRoot(env.piAgentDir, env.piSessionDir, join6(home, ".pi", "agent"));
6155
+ const piRoot = sessionsRoot(env.piAgentDir, env.piSessionDir, join7(home, ".pi", "agent"));
7792
6156
  const piExists = yield* sources.exists(piRoot);
7793
6157
  const hermesSourceRoot = hermesRoot(home, env);
7794
6158
  const hermesExists = yield* hermesSourceExistsEffect(hermesSourceRoot);
@@ -7826,10 +6190,10 @@ function buildFactoryFromPlan(plan) {
7826
6190
  });
7827
6191
  }
7828
6192
  function buildRealParserFactoryEffect(options = {}) {
7829
- return Effect22.map(resolveParserSourcePlanEffect(options), buildFactoryFromPlan);
6193
+ return Effect16.map(resolveParserSourcePlanEffect(options), buildFactoryFromPlan);
7830
6194
  }
7831
6195
  function buildRealParserFactory(options = {}) {
7832
- return buildRealParserFactoryEffect(options).pipe(Effect22.provide(ParserSourcesLive), Effect22.runSync);
6196
+ return buildRealParserFactoryEffect(options).pipe(Effect16.provide(ParserSourcesLive), Effect16.runSync);
7833
6197
  }
7834
6198
 
7835
6199
  // src/index.ts
@@ -7841,21 +6205,21 @@ var CliExit = class extends Error {
7841
6205
  this[Runtime.errorExitCode] = exitCode;
7842
6206
  }
7843
6207
  };
7844
- function readPackageVersion() {
7845
- const raw = readFileSync2(new URL("../package.json", import.meta.url), "utf8");
6208
+ function readPackageMetadata() {
6209
+ const raw = readFileSync3(new URL("../package.json", import.meta.url), "utf8");
7846
6210
  const parsed = JSON.parse(raw);
7847
- if (typeof parsed.version === "string" && parsed.version.length > 0) {
7848
- return parsed.version;
7849
- }
7850
- return "0.0.0";
6211
+ return {
6212
+ name: typeof parsed.name === "string" && parsed.name.length > 0 ? parsed.name : "@cookielab.io/oopst",
6213
+ version: typeof parsed.version === "string" && parsed.version.length > 0 ? parsed.version : "0.0.0"
6214
+ };
7851
6215
  }
7852
- var VERSION = readPackageVersion();
6216
+ var PACKAGE = readPackageMetadata();
7853
6217
  var SUPPORTED_HARNESSES = ["codex", "claude_code", "pi", "hermes", "opencode"];
7854
6218
  var cliOutputFormatter = {
7855
6219
  ...CliOutput.defaultFormatter({ colors: false }),
7856
6220
  formatVersion: (_name, version) => version
7857
6221
  };
7858
- var CliRuntimeLayer = Layer13.mergeAll(NodeServices.layer, CliOutput.layer(cliOutputFormatter));
6222
+ var CliRuntimeLayer = Layer8.mergeAll(NodeServices.layer, CliOutput.layer(cliOutputFormatter));
7859
6223
  function optionalValue(value) {
7860
6224
  return Option2.getOrUndefined(value);
7861
6225
  }
@@ -7872,7 +6236,7 @@ function writeUnknownError(err) {
7872
6236
  }
7873
6237
  function isEntrypoint() {
7874
6238
  const [, argvPath] = process5.argv;
7875
- return argvPath ? realpathSync(fileURLToPath2(import.meta.url)) === realpathSync(argvPath) : false;
6239
+ return argvPath ? realpathSync(fileURLToPath(import.meta.url)) === realpathSync(argvPath) : false;
7876
6240
  }
7877
6241
  function parseHarnessFilter(value) {
7878
6242
  if (value === void 0) {
@@ -7909,7 +6273,7 @@ async function runSyncCommand(raw) {
7909
6273
  sourcesExistedHint = real2.anySourceExisted;
7910
6274
  return real2;
7911
6275
  };
7912
- const result = await Effect23.runPromise(
6276
+ const result = await Effect17.runPromise(
7913
6277
  runSyncProgram({
7914
6278
  token,
7915
6279
  device,
@@ -7943,6 +6307,26 @@ async function runSyncCommand(raw) {
7943
6307
  return EXIT.generalFailure;
7944
6308
  }
7945
6309
  }
6310
+ async function runSetupCommand(raw) {
6311
+ try {
6312
+ const result = await runSetup({
6313
+ api: optionalValue(raw.api),
6314
+ server: optionalValue(raw.server),
6315
+ input: process5.stdin,
6316
+ output: process5.stdout,
6317
+ packageName: PACKAGE.name,
6318
+ nodePath: process5.execPath
6319
+ });
6320
+ return result.exitCode;
6321
+ } catch (err) {
6322
+ if (err instanceof CliConfigError || err instanceof SetupError) {
6323
+ writeStderrLine(err.message);
6324
+ return err instanceof SetupError ? err.exitCode : EXIT.invalidArguments;
6325
+ }
6326
+ writeUnknownError(err);
6327
+ return EXIT.generalFailure;
6328
+ }
6329
+ }
7946
6330
  var apiFlag = Flag.string("api").pipe(
7947
6331
  Flag.withDescription("API base URL (or server.api / OOPST_SERVER)"),
7948
6332
  Flag.optional
@@ -7982,17 +6366,27 @@ function buildCli() {
7982
6366
  dryRun: dryRunFlag,
7983
6367
  verbose: verboseFlag
7984
6368
  },
7985
- (raw) => Effect23.promise(() => runSyncCommand(raw)).pipe(
7986
- Effect23.flatMap((exitCode) => exitCode === EXIT.success ? Effect23.void : Effect23.fail(new CliExit(exitCode)))
6369
+ (raw) => Effect17.promise(() => runSyncCommand(raw)).pipe(
6370
+ Effect17.flatMap((exitCode) => exitCode === EXIT.success ? Effect17.void : Effect17.fail(new CliExit(exitCode)))
7987
6371
  )
7988
6372
  ).pipe(Command.withDescription("Scan local AI coding harness logs and upload hourly usage records"));
6373
+ const setup = Command.make(
6374
+ "setup",
6375
+ {
6376
+ api: apiFlag,
6377
+ server: serverFlag
6378
+ },
6379
+ (raw) => Effect17.promise(() => runSetupCommand(raw)).pipe(
6380
+ Effect17.flatMap((exitCode) => exitCode === EXIT.success ? Effect17.void : Effect17.fail(new CliExit(exitCode)))
6381
+ )
6382
+ ).pipe(Command.withDescription("Create ~/.oopst.yml and optionally install an hourly cron sync"));
7989
6383
  return Command.make("oopst").pipe(
7990
6384
  Command.withDescription("OopsT \u2014 track AI coding token usage across users and devices"),
7991
- Command.withSubcommands([sync])
6385
+ Command.withSubcommands([sync, setup])
7992
6386
  );
7993
6387
  }
7994
6388
  if (isEntrypoint()) {
7995
- buildCli().pipe(Command.run({ version: VERSION }), Effect23.provide(CliRuntimeLayer), NodeRuntime.runMain);
6389
+ buildCli().pipe(Command.run({ version: PACKAGE.version }), Effect17.provide(CliRuntimeLayer), NodeRuntime.runMain);
7996
6390
  }
7997
6391
  export {
7998
6392
  buildCli