@cookielab.io/oopst 0.2.0 → 0.3.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 +535 -79
- package/dist/index.js.map +1 -1
- package/package.json +47 -46
package/dist/index.js
CHANGED
|
@@ -21,9 +21,9 @@ var __commonJS = (cb, mod) => function __require2() {
|
|
|
21
21
|
};
|
|
22
22
|
var __copyProps = (to, from, except, desc) => {
|
|
23
23
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
24
|
-
for (let
|
|
25
|
-
if (!__hasOwnProp.call(to,
|
|
26
|
-
__defProp(to,
|
|
24
|
+
for (let key6 of __getOwnPropNames(from))
|
|
25
|
+
if (!__hasOwnProp.call(to, key6) && key6 !== except)
|
|
26
|
+
__defProp(to, key6, { get: () => from[key6], enumerable: !(desc = __getOwnPropDesc(from, key6)) || desc.enumerable });
|
|
27
27
|
}
|
|
28
28
|
return to;
|
|
29
29
|
};
|
|
@@ -1061,9 +1061,9 @@ var require_option = __commonJS({
|
|
|
1061
1061
|
this.positiveOptions.set(option.attributeName(), option);
|
|
1062
1062
|
}
|
|
1063
1063
|
});
|
|
1064
|
-
this.negativeOptions.forEach((value,
|
|
1065
|
-
if (this.positiveOptions.has(
|
|
1066
|
-
this.dualOptions.add(
|
|
1064
|
+
this.negativeOptions.forEach((value, key6) => {
|
|
1065
|
+
if (this.positiveOptions.has(key6)) {
|
|
1066
|
+
this.dualOptions.add(key6);
|
|
1067
1067
|
}
|
|
1068
1068
|
});
|
|
1069
1069
|
}
|
|
@@ -1998,11 +1998,11 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1998
1998
|
* @param {string} key
|
|
1999
1999
|
* @return {object} value
|
|
2000
2000
|
*/
|
|
2001
|
-
getOptionValue(
|
|
2001
|
+
getOptionValue(key6) {
|
|
2002
2002
|
if (this._storeOptionsAsProperties) {
|
|
2003
|
-
return this[
|
|
2003
|
+
return this[key6];
|
|
2004
2004
|
}
|
|
2005
|
-
return this._optionValues[
|
|
2005
|
+
return this._optionValues[key6];
|
|
2006
2006
|
}
|
|
2007
2007
|
/**
|
|
2008
2008
|
* Store option value.
|
|
@@ -2011,8 +2011,8 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2011
2011
|
* @param {object} value
|
|
2012
2012
|
* @return {Command} `this` command for chaining
|
|
2013
2013
|
*/
|
|
2014
|
-
setOptionValue(
|
|
2015
|
-
return this.setOptionValueWithSource(
|
|
2014
|
+
setOptionValue(key6, value) {
|
|
2015
|
+
return this.setOptionValueWithSource(key6, value, void 0);
|
|
2016
2016
|
}
|
|
2017
2017
|
/**
|
|
2018
2018
|
* Store option value and where the value came from.
|
|
@@ -2022,13 +2022,13 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2022
2022
|
* @param {string} source - expected values are default/config/env/cli/implied
|
|
2023
2023
|
* @return {Command} `this` command for chaining
|
|
2024
2024
|
*/
|
|
2025
|
-
setOptionValueWithSource(
|
|
2025
|
+
setOptionValueWithSource(key6, value, source) {
|
|
2026
2026
|
if (this._storeOptionsAsProperties) {
|
|
2027
|
-
this[
|
|
2027
|
+
this[key6] = value;
|
|
2028
2028
|
} else {
|
|
2029
|
-
this._optionValues[
|
|
2029
|
+
this._optionValues[key6] = value;
|
|
2030
2030
|
}
|
|
2031
|
-
this._optionValueSources[
|
|
2031
|
+
this._optionValueSources[key6] = source;
|
|
2032
2032
|
return this;
|
|
2033
2033
|
}
|
|
2034
2034
|
/**
|
|
@@ -2038,8 +2038,8 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2038
2038
|
* @param {string} key
|
|
2039
2039
|
* @return {string}
|
|
2040
2040
|
*/
|
|
2041
|
-
getOptionValueSource(
|
|
2042
|
-
return this._optionValueSources[
|
|
2041
|
+
getOptionValueSource(key6) {
|
|
2042
|
+
return this._optionValueSources[key6];
|
|
2043
2043
|
}
|
|
2044
2044
|
/**
|
|
2045
2045
|
* Get source of option value. See also .optsWithGlobals().
|
|
@@ -2048,11 +2048,11 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2048
2048
|
* @param {string} key
|
|
2049
2049
|
* @return {string}
|
|
2050
2050
|
*/
|
|
2051
|
-
getOptionValueSourceWithGlobals(
|
|
2051
|
+
getOptionValueSourceWithGlobals(key6) {
|
|
2052
2052
|
let source;
|
|
2053
2053
|
this._getCommandAndAncestors().forEach((cmd) => {
|
|
2054
|
-
if (cmd.getOptionValueSource(
|
|
2055
|
-
source = cmd.getOptionValueSource(
|
|
2054
|
+
if (cmd.getOptionValueSource(key6) !== void 0) {
|
|
2055
|
+
source = cmd.getOptionValueSource(key6);
|
|
2056
2056
|
}
|
|
2057
2057
|
});
|
|
2058
2058
|
return source;
|
|
@@ -2778,8 +2778,8 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2778
2778
|
const result = {};
|
|
2779
2779
|
const len = this.options.length;
|
|
2780
2780
|
for (let i = 0; i < len; i++) {
|
|
2781
|
-
const
|
|
2782
|
-
result[
|
|
2781
|
+
const key6 = this.options[i].attributeName();
|
|
2782
|
+
result[key6] = key6 === this._versionOptionName ? this._version : this[key6];
|
|
2783
2783
|
}
|
|
2784
2784
|
return result;
|
|
2785
2785
|
}
|
|
@@ -3524,7 +3524,9 @@ function readCliEnv() {
|
|
|
3524
3524
|
piAgentDir: runtimeEnv["PI_CODING_AGENT_DIR"],
|
|
3525
3525
|
piSessionDir: runtimeEnv["PI_CODING_AGENT_SESSION_DIR"],
|
|
3526
3526
|
hermesAgentDir: runtimeEnv["HERMES_CODING_AGENT_DIR"],
|
|
3527
|
-
hermesSessionDir: runtimeEnv["HERMES_CODING_AGENT_SESSION_DIR"]
|
|
3527
|
+
hermesSessionDir: runtimeEnv["HERMES_CODING_AGENT_SESSION_DIR"],
|
|
3528
|
+
opencodeDataDir: runtimeEnv["OPENCODE_DATA_DIR"],
|
|
3529
|
+
opencodeDbPath: runtimeEnv["OPENCODE_DB"]
|
|
3528
3530
|
};
|
|
3529
3531
|
}
|
|
3530
3532
|
|
|
@@ -3575,9 +3577,9 @@ function isNetworkError(err) {
|
|
|
3575
3577
|
|
|
3576
3578
|
// src/sync/parser-factory.ts
|
|
3577
3579
|
init_esm_shims();
|
|
3578
|
-
import { existsSync } from "fs";
|
|
3579
|
-
import { homedir as
|
|
3580
|
-
import { join as
|
|
3580
|
+
import { existsSync, readdirSync, statSync } from "fs";
|
|
3581
|
+
import { homedir as homedir5 } from "os";
|
|
3582
|
+
import { isAbsolute as isAbsolute2, join as join6 } from "path";
|
|
3581
3583
|
|
|
3582
3584
|
// ../../packages/parsers/src/index.ts
|
|
3583
3585
|
init_esm_shims();
|
|
@@ -3612,6 +3614,14 @@ function readHermesSessionDir() {
|
|
|
3612
3614
|
const value = runtimeEnv2["HERMES_CODING_AGENT_SESSION_DIR"]?.trim();
|
|
3613
3615
|
return value === void 0 || value.length === 0 ? void 0 : value;
|
|
3614
3616
|
}
|
|
3617
|
+
function readOpenCodeDataDir() {
|
|
3618
|
+
const value = runtimeEnv2["OPENCODE_DATA_DIR"]?.trim();
|
|
3619
|
+
return value === void 0 || value.length === 0 ? void 0 : value;
|
|
3620
|
+
}
|
|
3621
|
+
function readOpenCodeDbPath() {
|
|
3622
|
+
const value = runtimeEnv2["OPENCODE_DB"]?.trim();
|
|
3623
|
+
return value === void 0 || value.length === 0 ? void 0 : value;
|
|
3624
|
+
}
|
|
3615
3625
|
|
|
3616
3626
|
// ../../packages/parsers/src/types.ts
|
|
3617
3627
|
init_esm_shims();
|
|
@@ -4090,11 +4100,414 @@ async function* parseCodex(opts) {
|
|
|
4090
4100
|
}
|
|
4091
4101
|
}
|
|
4092
4102
|
|
|
4093
|
-
// ../../packages/parsers/src/
|
|
4103
|
+
// ../../packages/parsers/src/opencode/index.ts
|
|
4094
4104
|
init_esm_shims();
|
|
4095
|
-
import { stat as stat4 } from "fs/promises";
|
|
4105
|
+
import { readdir as readdir2, stat as stat4 } from "fs/promises";
|
|
4096
4106
|
import { homedir as homedir3 } from "os";
|
|
4097
|
-
import { join as join4 } from "path";
|
|
4107
|
+
import { basename, isAbsolute, join as join4 } from "path";
|
|
4108
|
+
|
|
4109
|
+
// ../../packages/parsers/src/opencode/bucketize.ts
|
|
4110
|
+
init_esm_shims();
|
|
4111
|
+
import { readFile } from "fs/promises";
|
|
4112
|
+
import { DatabaseSync } from "sqlite";
|
|
4113
|
+
|
|
4114
|
+
// ../../packages/parsers/src/opencode/events.ts
|
|
4115
|
+
init_esm_shims();
|
|
4116
|
+
function isObject3(value) {
|
|
4117
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
4118
|
+
}
|
|
4119
|
+
function isFiniteNumber3(value) {
|
|
4120
|
+
return typeof value === "number" && Number.isFinite(value);
|
|
4121
|
+
}
|
|
4122
|
+
function timestampMs(value) {
|
|
4123
|
+
if (isFiniteNumber3(value)) {
|
|
4124
|
+
return value;
|
|
4125
|
+
}
|
|
4126
|
+
if (typeof value !== "string") {
|
|
4127
|
+
return void 0;
|
|
4128
|
+
}
|
|
4129
|
+
const parsed = Date.parse(value);
|
|
4130
|
+
return Number.isFinite(parsed) ? parsed : void 0;
|
|
4131
|
+
}
|
|
4132
|
+
function isOpenCodeTokens(value) {
|
|
4133
|
+
if (!isObject3(value)) {
|
|
4134
|
+
return false;
|
|
4135
|
+
}
|
|
4136
|
+
const keys = ["input", "output", "reasoning"];
|
|
4137
|
+
for (const k of keys) {
|
|
4138
|
+
const v = value[k];
|
|
4139
|
+
if (v !== void 0 && !isFiniteNumber3(v)) {
|
|
4140
|
+
return false;
|
|
4141
|
+
}
|
|
4142
|
+
}
|
|
4143
|
+
const cache = value["cache"];
|
|
4144
|
+
if (cache !== void 0) {
|
|
4145
|
+
if (!isObject3(cache)) {
|
|
4146
|
+
return false;
|
|
4147
|
+
}
|
|
4148
|
+
for (const k of ["read", "write"]) {
|
|
4149
|
+
const v = cache[k];
|
|
4150
|
+
if (v !== void 0 && !isFiniteNumber3(v)) {
|
|
4151
|
+
return false;
|
|
4152
|
+
}
|
|
4153
|
+
}
|
|
4154
|
+
}
|
|
4155
|
+
return true;
|
|
4156
|
+
}
|
|
4157
|
+
function usageFromModernMessage(value, fallbackSessionId, fallbackTimestampMs) {
|
|
4158
|
+
const model = value["model"];
|
|
4159
|
+
if (!isObject3(model)) {
|
|
4160
|
+
return void 0;
|
|
4161
|
+
}
|
|
4162
|
+
const providerId = model["providerID"];
|
|
4163
|
+
const modelId3 = model["modelID"] ?? model["id"];
|
|
4164
|
+
if (typeof providerId !== "string" || typeof modelId3 !== "string") {
|
|
4165
|
+
return void 0;
|
|
4166
|
+
}
|
|
4167
|
+
const tokens = value["tokens"];
|
|
4168
|
+
if (!isOpenCodeTokens(tokens)) {
|
|
4169
|
+
return void 0;
|
|
4170
|
+
}
|
|
4171
|
+
const time = value["time"];
|
|
4172
|
+
const messageTimestampMs = isObject3(time) ? timestampMs(time["created"] ?? time["completed"]) : void 0;
|
|
4173
|
+
const sessionId = typeof value["sessionID"] === "string" ? value["sessionID"] : fallbackSessionId;
|
|
4174
|
+
const tsMs = messageTimestampMs ?? fallbackTimestampMs;
|
|
4175
|
+
if (sessionId === void 0 || tsMs === void 0) {
|
|
4176
|
+
return void 0;
|
|
4177
|
+
}
|
|
4178
|
+
return {
|
|
4179
|
+
sessionId,
|
|
4180
|
+
providerId,
|
|
4181
|
+
modelId: modelId3,
|
|
4182
|
+
timestampMs: tsMs,
|
|
4183
|
+
tokens
|
|
4184
|
+
};
|
|
4185
|
+
}
|
|
4186
|
+
function usageFromLegacyMessage(value, fallbackSessionId, fallbackTimestampMs) {
|
|
4187
|
+
if (value["role"] !== "assistant") {
|
|
4188
|
+
return void 0;
|
|
4189
|
+
}
|
|
4190
|
+
const providerId = value["providerID"];
|
|
4191
|
+
const modelId3 = value["modelID"];
|
|
4192
|
+
const tokens = value["tokens"];
|
|
4193
|
+
if (typeof providerId !== "string" || typeof modelId3 !== "string" || !isOpenCodeTokens(tokens)) {
|
|
4194
|
+
return void 0;
|
|
4195
|
+
}
|
|
4196
|
+
const time = value["time"];
|
|
4197
|
+
const messageTimestampMs = isObject3(time) ? timestampMs(time["created"] ?? time["completed"]) : void 0;
|
|
4198
|
+
const sessionId = typeof value["sessionID"] === "string" ? value["sessionID"] : fallbackSessionId;
|
|
4199
|
+
const tsMs = messageTimestampMs ?? fallbackTimestampMs;
|
|
4200
|
+
if (sessionId === void 0 || tsMs === void 0) {
|
|
4201
|
+
return void 0;
|
|
4202
|
+
}
|
|
4203
|
+
return {
|
|
4204
|
+
sessionId,
|
|
4205
|
+
providerId,
|
|
4206
|
+
modelId: modelId3,
|
|
4207
|
+
timestampMs: tsMs,
|
|
4208
|
+
tokens
|
|
4209
|
+
};
|
|
4210
|
+
}
|
|
4211
|
+
function usageFromMetadataMessage(value, fallbackSessionId, fallbackTimestampMs) {
|
|
4212
|
+
if (value["role"] !== "assistant") {
|
|
4213
|
+
return void 0;
|
|
4214
|
+
}
|
|
4215
|
+
const metadata = value["metadata"];
|
|
4216
|
+
if (!isObject3(metadata)) {
|
|
4217
|
+
return void 0;
|
|
4218
|
+
}
|
|
4219
|
+
const assistant = metadata["assistant"];
|
|
4220
|
+
if (!isObject3(assistant)) {
|
|
4221
|
+
return void 0;
|
|
4222
|
+
}
|
|
4223
|
+
const providerId = assistant["providerID"];
|
|
4224
|
+
const modelId3 = assistant["modelID"];
|
|
4225
|
+
const tokens = assistant["tokens"];
|
|
4226
|
+
if (typeof providerId !== "string" || typeof modelId3 !== "string" || !isOpenCodeTokens(tokens)) {
|
|
4227
|
+
return void 0;
|
|
4228
|
+
}
|
|
4229
|
+
const time = metadata["time"];
|
|
4230
|
+
const messageTimestampMs = isObject3(time) ? timestampMs(time["created"] ?? time["completed"]) : void 0;
|
|
4231
|
+
const sessionId = typeof metadata["sessionID"] === "string" ? metadata["sessionID"] : fallbackSessionId;
|
|
4232
|
+
const tsMs = messageTimestampMs ?? fallbackTimestampMs;
|
|
4233
|
+
if (sessionId === void 0 || tsMs === void 0) {
|
|
4234
|
+
return void 0;
|
|
4235
|
+
}
|
|
4236
|
+
return {
|
|
4237
|
+
sessionId,
|
|
4238
|
+
providerId,
|
|
4239
|
+
modelId: modelId3,
|
|
4240
|
+
timestampMs: tsMs,
|
|
4241
|
+
tokens
|
|
4242
|
+
};
|
|
4243
|
+
}
|
|
4244
|
+
function pickOpenCodeUsage(value, fallbackSessionId, fallbackTimestampMs) {
|
|
4245
|
+
if (!isObject3(value)) {
|
|
4246
|
+
return void 0;
|
|
4247
|
+
}
|
|
4248
|
+
return usageFromModernMessage(value, fallbackSessionId, fallbackTimestampMs) ?? usageFromLegacyMessage(value, fallbackSessionId, fallbackTimestampMs) ?? usageFromMetadataMessage(value, fallbackSessionId, fallbackTimestampMs);
|
|
4249
|
+
}
|
|
4250
|
+
|
|
4251
|
+
// ../../packages/parsers/src/opencode/bucketize.ts
|
|
4252
|
+
var MISSING_SESSION_MESSAGE_TABLE_PATTERN = /no such table: session_message/u;
|
|
4253
|
+
function key3(hourUtc, model, sessionId) {
|
|
4254
|
+
return `${hourUtc.toISOString()}|${model}|${sessionId}`;
|
|
4255
|
+
}
|
|
4256
|
+
function modelId(provider, model) {
|
|
4257
|
+
const trimmedProvider = provider.trim();
|
|
4258
|
+
const trimmedModel = model.trim();
|
|
4259
|
+
if (trimmedProvider.length === 0 || trimmedModel.length === 0) {
|
|
4260
|
+
return void 0;
|
|
4261
|
+
}
|
|
4262
|
+
return `${trimmedProvider}/${trimmedModel}`;
|
|
4263
|
+
}
|
|
4264
|
+
function finiteTimestampMs(value) {
|
|
4265
|
+
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
4266
|
+
}
|
|
4267
|
+
function positive(value) {
|
|
4268
|
+
return Math.max(0, value ?? 0);
|
|
4269
|
+
}
|
|
4270
|
+
function addUsage(accumulators, usage) {
|
|
4271
|
+
const model = modelId(usage.providerId, usage.modelId);
|
|
4272
|
+
if (model === void 0) {
|
|
4273
|
+
return;
|
|
4274
|
+
}
|
|
4275
|
+
const inputTokens = positive(usage.tokens.input);
|
|
4276
|
+
const outputTokens = positive(usage.tokens.output) + positive(usage.tokens.reasoning);
|
|
4277
|
+
const cacheReadTokens = positive(usage.tokens.cache?.read);
|
|
4278
|
+
const cacheCreateTokens = positive(usage.tokens.cache?.write);
|
|
4279
|
+
if (inputTokens === 0 && outputTokens === 0 && cacheReadTokens === 0 && cacheCreateTokens === 0) {
|
|
4280
|
+
return;
|
|
4281
|
+
}
|
|
4282
|
+
const eventAt = new Date(usage.timestampMs);
|
|
4283
|
+
const hourUtc = startOfUtcHour(eventAt);
|
|
4284
|
+
const sessionId = `opencode:${usage.sessionId}`;
|
|
4285
|
+
const accumulatorKey = key3(hourUtc, model, sessionId);
|
|
4286
|
+
const existing = accumulators.get(accumulatorKey);
|
|
4287
|
+
if (existing === void 0) {
|
|
4288
|
+
accumulators.set(accumulatorKey, {
|
|
4289
|
+
hourUtc,
|
|
4290
|
+
model,
|
|
4291
|
+
sessionId,
|
|
4292
|
+
inputTokens,
|
|
4293
|
+
outputTokens,
|
|
4294
|
+
cacheReadTokens,
|
|
4295
|
+
cacheCreateTokens,
|
|
4296
|
+
sessionStartedAt: eventAt,
|
|
4297
|
+
sessionLastSeenAt: eventAt
|
|
4298
|
+
});
|
|
4299
|
+
return;
|
|
4300
|
+
}
|
|
4301
|
+
existing.inputTokens += inputTokens;
|
|
4302
|
+
existing.outputTokens += outputTokens;
|
|
4303
|
+
existing.cacheReadTokens += cacheReadTokens;
|
|
4304
|
+
existing.cacheCreateTokens += cacheCreateTokens;
|
|
4305
|
+
if (eventAt.getTime() < existing.sessionStartedAt.getTime()) {
|
|
4306
|
+
existing.sessionStartedAt = eventAt;
|
|
4307
|
+
}
|
|
4308
|
+
if (eventAt.getTime() > existing.sessionLastSeenAt.getTime()) {
|
|
4309
|
+
existing.sessionLastSeenAt = eventAt;
|
|
4310
|
+
}
|
|
4311
|
+
}
|
|
4312
|
+
function* finalizedBuckets(accumulators) {
|
|
4313
|
+
for (const acc of accumulators.values()) {
|
|
4314
|
+
yield {
|
|
4315
|
+
harness: "opencode",
|
|
4316
|
+
model: acc.model,
|
|
4317
|
+
hourUtc: acc.hourUtc,
|
|
4318
|
+
inputTokens: acc.inputTokens,
|
|
4319
|
+
outputTokens: acc.outputTokens,
|
|
4320
|
+
cacheReadTokens: acc.cacheReadTokens,
|
|
4321
|
+
cacheCreateTokens: acc.cacheCreateTokens,
|
|
4322
|
+
sessionIds: /* @__PURE__ */ new Set([acc.sessionId]),
|
|
4323
|
+
sessionStartedAt: acc.sessionStartedAt,
|
|
4324
|
+
sessionLastSeenAt: acc.sessionLastSeenAt
|
|
4325
|
+
};
|
|
4326
|
+
}
|
|
4327
|
+
}
|
|
4328
|
+
function parseJson(value) {
|
|
4329
|
+
return typeof value === "string" ? JSON.parse(value) : value;
|
|
4330
|
+
}
|
|
4331
|
+
function isMissingTableError(err) {
|
|
4332
|
+
return err instanceof Error && MISSING_SESSION_MESSAGE_TABLE_PATTERN.test(err.message);
|
|
4333
|
+
}
|
|
4334
|
+
function* readSessionMessageRows(db, cutoff) {
|
|
4335
|
+
const statement = db.prepare(`
|
|
4336
|
+
select session_id as "sessionId", time_created as "timeCreated", data
|
|
4337
|
+
from session_message
|
|
4338
|
+
where type = 'assistant' and time_created >= ?
|
|
4339
|
+
order by time_created asc, id asc
|
|
4340
|
+
`);
|
|
4341
|
+
yield* statement.all(cutoff.getTime());
|
|
4342
|
+
}
|
|
4343
|
+
async function* bucketizeOpenCodeDatabase(path2, cutoff, logger) {
|
|
4344
|
+
const accumulators = /* @__PURE__ */ new Map();
|
|
4345
|
+
let db;
|
|
4346
|
+
try {
|
|
4347
|
+
db = new DatabaseSync(path2, { readOnly: true, timeout: 1e3 });
|
|
4348
|
+
for (const row of readSessionMessageRows(db, cutoff)) {
|
|
4349
|
+
const sessionId = typeof row.sessionId === "string" ? row.sessionId : void 0;
|
|
4350
|
+
const fallbackTimestampMs = finiteTimestampMs(row.timeCreated);
|
|
4351
|
+
let parsed;
|
|
4352
|
+
try {
|
|
4353
|
+
parsed = parseJson(row.data);
|
|
4354
|
+
} catch {
|
|
4355
|
+
logger.warn("malformed opencode sqlite message", { path: path2 });
|
|
4356
|
+
continue;
|
|
4357
|
+
}
|
|
4358
|
+
const usage = pickOpenCodeUsage(parsed, sessionId, fallbackTimestampMs);
|
|
4359
|
+
if (usage !== void 0) {
|
|
4360
|
+
addUsage(accumulators, usage);
|
|
4361
|
+
}
|
|
4362
|
+
}
|
|
4363
|
+
} catch (err) {
|
|
4364
|
+
if (!isMissingTableError(err)) {
|
|
4365
|
+
logger.warn("failed to parse opencode sqlite database", { path: path2 });
|
|
4366
|
+
}
|
|
4367
|
+
} finally {
|
|
4368
|
+
db?.close();
|
|
4369
|
+
}
|
|
4370
|
+
yield* finalizedBuckets(accumulators);
|
|
4371
|
+
}
|
|
4372
|
+
async function* bucketizeOpenCodeJsonFile(path2, logger) {
|
|
4373
|
+
let parsed;
|
|
4374
|
+
try {
|
|
4375
|
+
parsed = JSON.parse(await readFile(path2, "utf8"));
|
|
4376
|
+
} catch {
|
|
4377
|
+
logger.warn("malformed opencode json file", { path: path2 });
|
|
4378
|
+
return;
|
|
4379
|
+
}
|
|
4380
|
+
const usage = pickOpenCodeUsage(parsed);
|
|
4381
|
+
if (usage === void 0) {
|
|
4382
|
+
return;
|
|
4383
|
+
}
|
|
4384
|
+
const accumulators = /* @__PURE__ */ new Map();
|
|
4385
|
+
addUsage(accumulators, usage);
|
|
4386
|
+
yield* finalizedBuckets(accumulators);
|
|
4387
|
+
}
|
|
4388
|
+
|
|
4389
|
+
// ../../packages/parsers/src/opencode/index.ts
|
|
4390
|
+
var OPENCODE_DB_FILE_PATTERN = /^opencode(?:-[^/]+)?\.db$/u;
|
|
4391
|
+
async function pathKind(path2) {
|
|
4392
|
+
try {
|
|
4393
|
+
const s = await stat4(path2);
|
|
4394
|
+
if (s.isFile()) {
|
|
4395
|
+
return "file";
|
|
4396
|
+
}
|
|
4397
|
+
if (s.isDirectory()) {
|
|
4398
|
+
return "directory";
|
|
4399
|
+
}
|
|
4400
|
+
return "missing";
|
|
4401
|
+
} catch {
|
|
4402
|
+
return "missing";
|
|
4403
|
+
}
|
|
4404
|
+
}
|
|
4405
|
+
function defaultDataRoot() {
|
|
4406
|
+
return readOpenCodeDataDir() ?? join4(homedir3(), ".local", "share", "opencode");
|
|
4407
|
+
}
|
|
4408
|
+
function resolveDefaultRoot() {
|
|
4409
|
+
const dbPath = readOpenCodeDbPath();
|
|
4410
|
+
if (dbPath === void 0) {
|
|
4411
|
+
return defaultDataRoot();
|
|
4412
|
+
}
|
|
4413
|
+
if (dbPath === ":memory:") {
|
|
4414
|
+
return dbPath;
|
|
4415
|
+
}
|
|
4416
|
+
if (isAbsolute(dbPath)) {
|
|
4417
|
+
return dbPath;
|
|
4418
|
+
}
|
|
4419
|
+
return join4(defaultDataRoot(), dbPath);
|
|
4420
|
+
}
|
|
4421
|
+
async function listOpenCodeDatabases(root) {
|
|
4422
|
+
let entries;
|
|
4423
|
+
try {
|
|
4424
|
+
entries = await readdir2(root, { withFileTypes: true });
|
|
4425
|
+
} catch {
|
|
4426
|
+
return [];
|
|
4427
|
+
}
|
|
4428
|
+
return entries.filter((entry) => entry.isFile() && OPENCODE_DB_FILE_PATTERN.test(String(entry.name))).map((entry) => join4(root, String(entry.name)));
|
|
4429
|
+
}
|
|
4430
|
+
async function listProjectLegacyRoots(root) {
|
|
4431
|
+
const projectRoot = join4(root, "project");
|
|
4432
|
+
let entries;
|
|
4433
|
+
try {
|
|
4434
|
+
entries = await readdir2(projectRoot, { withFileTypes: true });
|
|
4435
|
+
} catch {
|
|
4436
|
+
return [];
|
|
4437
|
+
}
|
|
4438
|
+
return entries.filter((entry) => entry.isDirectory()).flatMap((entry) => [
|
|
4439
|
+
join4(projectRoot, String(entry.name), "storage", "message"),
|
|
4440
|
+
join4(projectRoot, String(entry.name), "storage", "session", "message")
|
|
4441
|
+
]);
|
|
4442
|
+
}
|
|
4443
|
+
async function legacyRoots(root) {
|
|
4444
|
+
return [
|
|
4445
|
+
join4(root, "storage", "message"),
|
|
4446
|
+
join4(root, "storage", "session", "message"),
|
|
4447
|
+
...await listProjectLegacyRoots(root)
|
|
4448
|
+
];
|
|
4449
|
+
}
|
|
4450
|
+
async function* walkJson(root, cutoff) {
|
|
4451
|
+
let entries;
|
|
4452
|
+
try {
|
|
4453
|
+
entries = await readdir2(root, { withFileTypes: true });
|
|
4454
|
+
} catch {
|
|
4455
|
+
return;
|
|
4456
|
+
}
|
|
4457
|
+
for (const entry of entries) {
|
|
4458
|
+
const full = join4(root, String(entry.name));
|
|
4459
|
+
if (entry.isDirectory()) {
|
|
4460
|
+
yield* walkJson(full, cutoff);
|
|
4461
|
+
continue;
|
|
4462
|
+
}
|
|
4463
|
+
if (!(entry.isFile() && entry.name.endsWith(".json"))) {
|
|
4464
|
+
continue;
|
|
4465
|
+
}
|
|
4466
|
+
let mtime;
|
|
4467
|
+
try {
|
|
4468
|
+
({ mtime } = await stat4(full));
|
|
4469
|
+
} catch {
|
|
4470
|
+
continue;
|
|
4471
|
+
}
|
|
4472
|
+
if (mtime.getTime() >= cutoff.getTime()) {
|
|
4473
|
+
yield full;
|
|
4474
|
+
}
|
|
4475
|
+
}
|
|
4476
|
+
}
|
|
4477
|
+
async function* parseOpenCode(opts) {
|
|
4478
|
+
const logger = opts.logger ?? consoleLogger;
|
|
4479
|
+
const root = opts.root ?? resolveDefaultRoot();
|
|
4480
|
+
const kind = await pathKind(root);
|
|
4481
|
+
if (kind === "missing") {
|
|
4482
|
+
return;
|
|
4483
|
+
}
|
|
4484
|
+
if (kind === "file") {
|
|
4485
|
+
if (basename(root).endsWith(".json")) {
|
|
4486
|
+
yield* bucketizeOpenCodeJsonFile(root, logger);
|
|
4487
|
+
return;
|
|
4488
|
+
}
|
|
4489
|
+
yield* bucketizeOpenCodeDatabase(root, opts.cutoff, logger);
|
|
4490
|
+
return;
|
|
4491
|
+
}
|
|
4492
|
+
const databases = await listOpenCodeDatabases(root);
|
|
4493
|
+
if (databases.length > 0) {
|
|
4494
|
+
for (const dbPath of databases) {
|
|
4495
|
+
yield* bucketizeOpenCodeDatabase(dbPath, opts.cutoff, logger);
|
|
4496
|
+
}
|
|
4497
|
+
return;
|
|
4498
|
+
}
|
|
4499
|
+
for (const legacyRoot of await legacyRoots(root)) {
|
|
4500
|
+
for await (const file of walkJson(legacyRoot, opts.cutoff)) {
|
|
4501
|
+
yield* bucketizeOpenCodeJsonFile(file, logger);
|
|
4502
|
+
}
|
|
4503
|
+
}
|
|
4504
|
+
}
|
|
4505
|
+
|
|
4506
|
+
// ../../packages/parsers/src/pi/index.ts
|
|
4507
|
+
init_esm_shims();
|
|
4508
|
+
import { stat as stat5 } from "fs/promises";
|
|
4509
|
+
import { homedir as homedir4 } from "os";
|
|
4510
|
+
import { join as join5 } from "path";
|
|
4098
4511
|
|
|
4099
4512
|
// ../../packages/parsers/src/pi/bucketize.ts
|
|
4100
4513
|
init_esm_shims();
|
|
@@ -4103,27 +4516,27 @@ import { createInterface as createInterface3 } from "readline";
|
|
|
4103
4516
|
|
|
4104
4517
|
// ../../packages/parsers/src/pi/events.ts
|
|
4105
4518
|
init_esm_shims();
|
|
4106
|
-
function
|
|
4519
|
+
function isObject4(value) {
|
|
4107
4520
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
4108
4521
|
}
|
|
4109
|
-
function
|
|
4522
|
+
function isFiniteNumber4(value) {
|
|
4110
4523
|
return typeof value === "number" && Number.isFinite(value);
|
|
4111
4524
|
}
|
|
4112
4525
|
function isPiUsage(value) {
|
|
4113
|
-
if (!
|
|
4526
|
+
if (!isObject4(value)) {
|
|
4114
4527
|
return false;
|
|
4115
4528
|
}
|
|
4116
4529
|
const keys = ["input", "output", "cacheRead", "cacheWrite"];
|
|
4117
4530
|
for (const k of keys) {
|
|
4118
4531
|
const v = value[k];
|
|
4119
|
-
if (v !== void 0 && !
|
|
4532
|
+
if (v !== void 0 && !isFiniteNumber4(v)) {
|
|
4120
4533
|
return false;
|
|
4121
4534
|
}
|
|
4122
4535
|
}
|
|
4123
4536
|
return true;
|
|
4124
4537
|
}
|
|
4125
4538
|
function isPiAssistantMessageEntry(value) {
|
|
4126
|
-
if (!
|
|
4539
|
+
if (!isObject4(value)) {
|
|
4127
4540
|
return false;
|
|
4128
4541
|
}
|
|
4129
4542
|
if (value["type"] !== "message") {
|
|
@@ -4133,7 +4546,7 @@ function isPiAssistantMessageEntry(value) {
|
|
|
4133
4546
|
return false;
|
|
4134
4547
|
}
|
|
4135
4548
|
const message = value["message"];
|
|
4136
|
-
if (!
|
|
4549
|
+
if (!isObject4(message)) {
|
|
4137
4550
|
return false;
|
|
4138
4551
|
}
|
|
4139
4552
|
if (message["role"] !== "assistant") {
|
|
@@ -4148,7 +4561,7 @@ function isPiAssistantMessageEntry(value) {
|
|
|
4148
4561
|
if (message["stopReason"] !== void 0 && typeof message["stopReason"] !== "string") {
|
|
4149
4562
|
return false;
|
|
4150
4563
|
}
|
|
4151
|
-
if (message["timestamp"] !== void 0 && !
|
|
4564
|
+
if (message["timestamp"] !== void 0 && !isFiniteNumber4(message["timestamp"])) {
|
|
4152
4565
|
return false;
|
|
4153
4566
|
}
|
|
4154
4567
|
if (!isPiUsage(message["usage"])) {
|
|
@@ -4158,7 +4571,7 @@ function isPiAssistantMessageEntry(value) {
|
|
|
4158
4571
|
}
|
|
4159
4572
|
|
|
4160
4573
|
// ../../packages/parsers/src/pi/bucketize.ts
|
|
4161
|
-
function
|
|
4574
|
+
function key4(hourUtc, model) {
|
|
4162
4575
|
return `${hourUtc.toISOString()}|${model}`;
|
|
4163
4576
|
}
|
|
4164
4577
|
function eventTimestampMs(entry) {
|
|
@@ -4167,7 +4580,7 @@ function eventTimestampMs(entry) {
|
|
|
4167
4580
|
}
|
|
4168
4581
|
return Date.parse(entry.timestamp);
|
|
4169
4582
|
}
|
|
4170
|
-
function
|
|
4583
|
+
function modelId2(provider, model) {
|
|
4171
4584
|
const trimmedProvider = provider.trim();
|
|
4172
4585
|
const trimmedModel = model.trim();
|
|
4173
4586
|
if (trimmedProvider.length === 0 || trimmedModel.length === 0) {
|
|
@@ -4206,7 +4619,7 @@ async function* bucketizePiStyleFile(path2, harness, logger) {
|
|
|
4206
4619
|
if (!Number.isFinite(tsMs)) {
|
|
4207
4620
|
continue;
|
|
4208
4621
|
}
|
|
4209
|
-
const model =
|
|
4622
|
+
const model = modelId2(parsed.message.provider, parsed.message.model);
|
|
4210
4623
|
if (model === void 0) {
|
|
4211
4624
|
continue;
|
|
4212
4625
|
}
|
|
@@ -4226,7 +4639,7 @@ async function* bucketizePiStyleFile(path2, harness, logger) {
|
|
|
4226
4639
|
sessionLastSeenAt = eventAt;
|
|
4227
4640
|
}
|
|
4228
4641
|
const hourUtc = startOfUtcHour(eventAt);
|
|
4229
|
-
const k =
|
|
4642
|
+
const k = key4(hourUtc, model);
|
|
4230
4643
|
const existing = buckets.get(k);
|
|
4231
4644
|
if (existing === void 0) {
|
|
4232
4645
|
buckets.set(k, {
|
|
@@ -4271,7 +4684,7 @@ async function* bucketizePiStyleFile(path2, harness, logger) {
|
|
|
4271
4684
|
// ../../packages/parsers/src/pi/index.ts
|
|
4272
4685
|
async function isFile3(path2) {
|
|
4273
4686
|
try {
|
|
4274
|
-
return (await
|
|
4687
|
+
return (await stat5(path2)).isFile();
|
|
4275
4688
|
} catch {
|
|
4276
4689
|
return false;
|
|
4277
4690
|
}
|
|
@@ -4281,14 +4694,14 @@ function defaultPiRoot() {
|
|
|
4281
4694
|
if (sessionDir !== void 0) {
|
|
4282
4695
|
return sessionDir;
|
|
4283
4696
|
}
|
|
4284
|
-
return
|
|
4697
|
+
return join5(readPiAgentDir() ?? join5(homedir4(), ".pi", "agent"), "sessions");
|
|
4285
4698
|
}
|
|
4286
4699
|
function defaultHermesRoot() {
|
|
4287
4700
|
const sessionDir = readHermesSessionDir();
|
|
4288
4701
|
if (sessionDir !== void 0) {
|
|
4289
4702
|
return sessionDir;
|
|
4290
4703
|
}
|
|
4291
|
-
return
|
|
4704
|
+
return join5(readHermesAgentDir() ?? join5(homedir4(), ".hermes", "agent"), "sessions");
|
|
4292
4705
|
}
|
|
4293
4706
|
async function* parsePiStyle(opts, harness, defaultRoot2) {
|
|
4294
4707
|
const logger = opts.logger ?? consoleLogger;
|
|
@@ -4309,29 +4722,69 @@ async function* parseHermes(opts) {
|
|
|
4309
4722
|
}
|
|
4310
4723
|
|
|
4311
4724
|
// src/sync/parser-factory.ts
|
|
4725
|
+
var OPENCODE_DB_FILE_PATTERN2 = /^opencode(?:-[^/]+)?\.db$/u;
|
|
4312
4726
|
function sessionsRoot(agentDir, sessionDir, fallbackAgentDir) {
|
|
4313
|
-
return sessionDir ??
|
|
4727
|
+
return sessionDir ?? join6(agentDir ?? fallbackAgentDir, "sessions");
|
|
4728
|
+
}
|
|
4729
|
+
function isFile4(path2) {
|
|
4730
|
+
try {
|
|
4731
|
+
return statSync(path2).isFile();
|
|
4732
|
+
} catch {
|
|
4733
|
+
return false;
|
|
4734
|
+
}
|
|
4735
|
+
}
|
|
4736
|
+
function defaultOpenCodeDataRoot(home) {
|
|
4737
|
+
return join6(home, ".local", "share", "opencode");
|
|
4738
|
+
}
|
|
4739
|
+
function openCodeRoot(home, env) {
|
|
4740
|
+
const dataRoot = env.opencodeDataDir ?? defaultOpenCodeDataRoot(home);
|
|
4741
|
+
const dbPath = env.opencodeDbPath;
|
|
4742
|
+
if (dbPath === void 0 || dbPath === ":memory:") {
|
|
4743
|
+
return dbPath ?? dataRoot;
|
|
4744
|
+
}
|
|
4745
|
+
return isAbsolute2(dbPath) ? dbPath : join6(dataRoot, dbPath);
|
|
4746
|
+
}
|
|
4747
|
+
function hasOpenCodeDatabase(root) {
|
|
4748
|
+
let entries;
|
|
4749
|
+
try {
|
|
4750
|
+
entries = readdirSync(root);
|
|
4751
|
+
} catch {
|
|
4752
|
+
return false;
|
|
4753
|
+
}
|
|
4754
|
+
return entries.some((entry) => OPENCODE_DB_FILE_PATTERN2.test(entry) && isFile4(join6(root, entry)));
|
|
4755
|
+
}
|
|
4756
|
+
function openCodeSourceExists(root) {
|
|
4757
|
+
if (root === ":memory:") {
|
|
4758
|
+
return false;
|
|
4759
|
+
}
|
|
4760
|
+
if (isFile4(root)) {
|
|
4761
|
+
return true;
|
|
4762
|
+
}
|
|
4763
|
+
return hasOpenCodeDatabase(root) || existsSync(join6(root, "storage", "message")) || existsSync(join6(root, "storage", "session", "message")) || existsSync(join6(root, "project"));
|
|
4314
4764
|
}
|
|
4315
4765
|
function buildRealParserFactory() {
|
|
4316
4766
|
return (ctx) => {
|
|
4317
|
-
const home =
|
|
4767
|
+
const home = homedir5();
|
|
4318
4768
|
const env = readCliEnv();
|
|
4319
|
-
const codexSessionsRoot =
|
|
4320
|
-
const codexArchivedRoot =
|
|
4769
|
+
const codexSessionsRoot = join6(home, ".codex", "sessions");
|
|
4770
|
+
const codexArchivedRoot = join6(home, ".codex", "archived_sessions");
|
|
4321
4771
|
const codexExists = existsSync(codexSessionsRoot) || existsSync(codexArchivedRoot);
|
|
4322
4772
|
const envDir = env.claudeConfigDir;
|
|
4323
|
-
const claudeRoot = envDir == null ?
|
|
4773
|
+
const claudeRoot = envDir == null ? join6(home, ".claude", "projects") : join6(envDir, "projects");
|
|
4324
4774
|
const claudeExists = existsSync(claudeRoot);
|
|
4325
|
-
const piRoot = sessionsRoot(env.piAgentDir, env.piSessionDir,
|
|
4775
|
+
const piRoot = sessionsRoot(env.piAgentDir, env.piSessionDir, join6(home, ".pi", "agent"));
|
|
4326
4776
|
const piExists = existsSync(piRoot);
|
|
4327
|
-
const hermesRoot = sessionsRoot(env.hermesAgentDir, env.hermesSessionDir,
|
|
4777
|
+
const hermesRoot = sessionsRoot(env.hermesAgentDir, env.hermesSessionDir, join6(home, ".hermes", "agent"));
|
|
4328
4778
|
const hermesExists = existsSync(hermesRoot);
|
|
4779
|
+
const opencodeRoot = openCodeRoot(home, env);
|
|
4780
|
+
const opencodeExists = openCodeSourceExists(opencodeRoot);
|
|
4329
4781
|
return {
|
|
4330
|
-
anySourceExisted: codexExists || claudeExists || piExists || hermesExists,
|
|
4782
|
+
anySourceExisted: codexExists || claudeExists || piExists || hermesExists || opencodeExists,
|
|
4331
4783
|
codex: parseCodex({ cutoff: ctx.cutoff }),
|
|
4332
4784
|
claudeCode: parseClaude({ cutoff: ctx.cutoff, root: claudeRoot }),
|
|
4333
4785
|
pi: parsePi({ cutoff: ctx.cutoff, root: piRoot }),
|
|
4334
|
-
hermes: parseHermes({ cutoff: ctx.cutoff, root: hermesRoot })
|
|
4786
|
+
hermes: parseHermes({ cutoff: ctx.cutoff, root: hermesRoot }),
|
|
4787
|
+
opencode: parseOpenCode({ cutoff: ctx.cutoff, root: opencodeRoot })
|
|
4335
4788
|
};
|
|
4336
4789
|
};
|
|
4337
4790
|
}
|
|
@@ -4345,7 +4798,7 @@ import { createHmac } from "crypto";
|
|
|
4345
4798
|
function toIso(hourUtc) {
|
|
4346
4799
|
return hourUtc instanceof Date ? hourUtc.toISOString() : hourUtc;
|
|
4347
4800
|
}
|
|
4348
|
-
function
|
|
4801
|
+
function key5(b) {
|
|
4349
4802
|
return `${b.harness} ${b.model} ${toIso(b.hourUtc)}`;
|
|
4350
4803
|
}
|
|
4351
4804
|
function finalize(acc) {
|
|
@@ -4402,7 +4855,7 @@ async function* aggregateUsage(source, options) {
|
|
|
4402
4855
|
const accumulators = /* @__PURE__ */ new Map();
|
|
4403
4856
|
const sessionAccumulators = /* @__PURE__ */ new Map();
|
|
4404
4857
|
for await (const bucket of source) {
|
|
4405
|
-
const k =
|
|
4858
|
+
const k = key5(bucket);
|
|
4406
4859
|
let acc = accumulators.get(k);
|
|
4407
4860
|
if (!acc) {
|
|
4408
4861
|
acc = {
|
|
@@ -4461,11 +4914,11 @@ var __commonJS2 = (cb, mod) => function() {
|
|
|
4461
4914
|
return mod || (0, cb[__getOwnPropNames2(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
4462
4915
|
};
|
|
4463
4916
|
var __copyProps2 = (to, from, except, desc) => {
|
|
4464
|
-
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames2(from), i = 0, n = keys.length,
|
|
4465
|
-
|
|
4466
|
-
if (!__hasOwnProp2.call(to,
|
|
4467
|
-
get: ((k) => from[k]).bind(null,
|
|
4468
|
-
enumerable: !(desc = __getOwnPropDesc2(from,
|
|
4917
|
+
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames2(from), i = 0, n = keys.length, key6; i < n; i++) {
|
|
4918
|
+
key6 = keys[i];
|
|
4919
|
+
if (!__hasOwnProp2.call(to, key6) && key6 !== except) __defProp2(to, key6, {
|
|
4920
|
+
get: ((k) => from[k]).bind(null, key6),
|
|
4921
|
+
enumerable: !(desc = __getOwnPropDesc2(from, key6)) || desc.enumerable
|
|
4469
4922
|
});
|
|
4470
4923
|
}
|
|
4471
4924
|
return to;
|
|
@@ -4740,7 +5193,7 @@ init_esm_shims();
|
|
|
4740
5193
|
|
|
4741
5194
|
// ../../node_modules/.pnpm/@trpc+server@11.17.0_typescript@6.0.3/node_modules/@trpc/server/dist/codes-DagpWZLc.mjs
|
|
4742
5195
|
init_esm_shims();
|
|
4743
|
-
function
|
|
5196
|
+
function isObject5(value) {
|
|
4744
5197
|
return !!value && !Array.isArray(value) && typeof value === "object";
|
|
4745
5198
|
}
|
|
4746
5199
|
function emptyObject() {
|
|
@@ -4787,11 +5240,11 @@ var __commonJS3 = (cb, mod) => function() {
|
|
|
4787
5240
|
return mod || (0, cb[__getOwnPropNames3(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
4788
5241
|
};
|
|
4789
5242
|
var __copyProps3 = (to, from, except, desc) => {
|
|
4790
|
-
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames3(from), i = 0, n = keys.length,
|
|
4791
|
-
|
|
4792
|
-
if (!__hasOwnProp3.call(to,
|
|
4793
|
-
get: ((k) => from[k]).bind(null,
|
|
4794
|
-
enumerable: !(desc = __getOwnPropDesc3(from,
|
|
5243
|
+
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames3(from), i = 0, n = keys.length, key6; i < n; i++) {
|
|
5244
|
+
key6 = keys[i];
|
|
5245
|
+
if (!__hasOwnProp3.call(to, key6) && key6 !== except) __defProp3(to, key6, {
|
|
5246
|
+
get: ((k) => from[k]).bind(null, key6),
|
|
5247
|
+
enumerable: !(desc = __getOwnPropDesc3(from, key6)) || desc.enumerable
|
|
4795
5248
|
});
|
|
4796
5249
|
}
|
|
4797
5250
|
return to;
|
|
@@ -4809,9 +5262,9 @@ function createInnerProxy(callback, path2, memo) {
|
|
|
4809
5262
|
var _memo$cacheKey;
|
|
4810
5263
|
const cacheKey = path2.join(".");
|
|
4811
5264
|
(_memo$cacheKey = memo[cacheKey]) !== null && _memo$cacheKey !== void 0 || (memo[cacheKey] = new Proxy(noop, {
|
|
4812
|
-
get(_obj,
|
|
4813
|
-
if (typeof
|
|
4814
|
-
return createInnerProxy(callback, [...path2,
|
|
5265
|
+
get(_obj, key6) {
|
|
5266
|
+
if (typeof key6 !== "string" || key6 === "then") return void 0;
|
|
5267
|
+
return createInnerProxy(callback, [...path2, key6], memo);
|
|
4815
5268
|
},
|
|
4816
5269
|
apply(_1, _2, args) {
|
|
4817
5270
|
const lastOfPath = path2[path2.length - 1];
|
|
@@ -4951,8 +5404,8 @@ function transformResult(response, transformer) {
|
|
|
4951
5404
|
} catch (_unused) {
|
|
4952
5405
|
throw new TransformResultError();
|
|
4953
5406
|
}
|
|
4954
|
-
if (!result.ok && (!
|
|
4955
|
-
if (result.ok && !
|
|
5407
|
+
if (!result.ok && (!isObject5(result.error.error) || typeof result.error.error["code"] !== "number")) throw new TransformResultError();
|
|
5408
|
+
if (result.ok && !isObject5(result.result)) throw new TransformResultError();
|
|
4956
5409
|
return result;
|
|
4957
5410
|
}
|
|
4958
5411
|
var import_objectSpread22 = __toESM3(require_objectSpread22(), 1);
|
|
@@ -4964,11 +5417,11 @@ function isTRPCClientError(cause) {
|
|
|
4964
5417
|
return cause instanceof TRPCClientError;
|
|
4965
5418
|
}
|
|
4966
5419
|
function isTRPCErrorResponse(obj) {
|
|
4967
|
-
return
|
|
5420
|
+
return isObject5(obj) && isObject5(obj["error"]) && typeof obj["error"]["code"] === "number" && typeof obj["error"]["message"] === "string";
|
|
4968
5421
|
}
|
|
4969
5422
|
function getMessageFromUnknownError(err, fallback) {
|
|
4970
5423
|
if (typeof err === "string") return err;
|
|
4971
|
-
if (
|
|
5424
|
+
if (isObject5(err) && typeof err["message"] === "string") return err["message"];
|
|
4972
5425
|
return fallback;
|
|
4973
5426
|
}
|
|
4974
5427
|
var TRPCClientError = class TRPCClientError2 extends Error {
|
|
@@ -5213,11 +5666,11 @@ function dataLoader(batchLoader) {
|
|
|
5213
5666
|
});
|
|
5214
5667
|
}
|
|
5215
5668
|
}
|
|
5216
|
-
function load(
|
|
5669
|
+
function load(key6) {
|
|
5217
5670
|
var _dispatchTimer;
|
|
5218
5671
|
const item = {
|
|
5219
5672
|
aborted: false,
|
|
5220
|
-
key:
|
|
5673
|
+
key: key6,
|
|
5221
5674
|
batch: null,
|
|
5222
5675
|
resolve: throwFatalError,
|
|
5223
5676
|
reject: throwFatalError
|
|
@@ -5592,9 +6045,9 @@ function createTRPCClientProxy(client) {
|
|
|
5592
6045
|
const fullPath = pathCopy.join(".");
|
|
5593
6046
|
return client[procedureType](fullPath, ...args);
|
|
5594
6047
|
});
|
|
5595
|
-
return createFlatProxy((
|
|
5596
|
-
if (
|
|
5597
|
-
return proxy[
|
|
6048
|
+
return createFlatProxy((key6) => {
|
|
6049
|
+
if (key6 === untypedClientSymbol) return client;
|
|
6050
|
+
return proxy[key6];
|
|
5598
6051
|
});
|
|
5599
6052
|
}
|
|
5600
6053
|
function createTRPCClient(opts) {
|
|
@@ -5860,6 +6313,9 @@ async function runSync(options) {
|
|
|
5860
6313
|
if (options.harness === void 0 || options.harness === "hermes") {
|
|
5861
6314
|
sources.push({ label: "Hermes", source: parsers.hermes });
|
|
5862
6315
|
}
|
|
6316
|
+
if (options.harness === void 0 || options.harness === "opencode") {
|
|
6317
|
+
sources.push({ label: "OpenCode", source: parsers.opencode });
|
|
6318
|
+
}
|
|
5863
6319
|
let bucketsUploaded = 0;
|
|
5864
6320
|
let sessionsUploaded = 0;
|
|
5865
6321
|
let batchesUploaded = 0;
|
|
@@ -6034,7 +6490,7 @@ function readPackageVersion() {
|
|
|
6034
6490
|
return "0.0.0";
|
|
6035
6491
|
}
|
|
6036
6492
|
var VERSION = readPackageVersion();
|
|
6037
|
-
var SUPPORTED_HARNESSES = ["codex", "claude_code", "pi", "hermes"];
|
|
6493
|
+
var SUPPORTED_HARNESSES = ["codex", "claude_code", "pi", "hermes", "opencode"];
|
|
6038
6494
|
function writeStdoutLine(msg) {
|
|
6039
6495
|
process4.stdout.write(`${msg}
|
|
6040
6496
|
`);
|
|
@@ -6068,7 +6524,7 @@ function buildCli() {
|
|
|
6068
6524
|
const env = readCliEnv();
|
|
6069
6525
|
const program2 = new Command();
|
|
6070
6526
|
program2.name("oopst").description("OopsT \u2014 track AI coding token usage across users and devices").version(VERSION).exitOverride();
|
|
6071
|
-
program2.command("sync").description("Scan local
|
|
6527
|
+
program2.command("sync").description("Scan local AI coding harness logs and upload hourly usage records").option("--token <token>", "CLI API token (or OOPST_TOKEN env)").option("--device <name>", "Device name (or OOPST_DEVICE env)").option("--server <url>", "Server base URL", env.serverUrl).option("--lookback-days <days>", "Override watermark lookback", DEFAULT_LOOKBACK_DAYS).option("--harness <harness>", "Restrict to codex|claude_code|pi|hermes|opencode").option("--dry-run", "Parse and print without uploading", false).option("--verbose", "Verbose logs", false).action(
|
|
6072
6528
|
async (raw) => {
|
|
6073
6529
|
const token = raw.token ?? env.token;
|
|
6074
6530
|
const device = raw.device ?? env.device;
|