@cookielab.io/oopst 0.2.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +540 -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,419 @@ 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
|
+
|
|
4113
|
+
// ../../packages/parsers/src/opencode/events.ts
|
|
4114
|
+
init_esm_shims();
|
|
4115
|
+
function isObject3(value) {
|
|
4116
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
4117
|
+
}
|
|
4118
|
+
function isFiniteNumber3(value) {
|
|
4119
|
+
return typeof value === "number" && Number.isFinite(value);
|
|
4120
|
+
}
|
|
4121
|
+
function timestampMs(value) {
|
|
4122
|
+
if (isFiniteNumber3(value)) {
|
|
4123
|
+
return value;
|
|
4124
|
+
}
|
|
4125
|
+
if (typeof value !== "string") {
|
|
4126
|
+
return void 0;
|
|
4127
|
+
}
|
|
4128
|
+
const parsed = Date.parse(value);
|
|
4129
|
+
return Number.isFinite(parsed) ? parsed : void 0;
|
|
4130
|
+
}
|
|
4131
|
+
function isOpenCodeTokens(value) {
|
|
4132
|
+
if (!isObject3(value)) {
|
|
4133
|
+
return false;
|
|
4134
|
+
}
|
|
4135
|
+
const keys = ["input", "output", "reasoning"];
|
|
4136
|
+
for (const k of keys) {
|
|
4137
|
+
const v = value[k];
|
|
4138
|
+
if (v !== void 0 && !isFiniteNumber3(v)) {
|
|
4139
|
+
return false;
|
|
4140
|
+
}
|
|
4141
|
+
}
|
|
4142
|
+
const cache = value["cache"];
|
|
4143
|
+
if (cache !== void 0) {
|
|
4144
|
+
if (!isObject3(cache)) {
|
|
4145
|
+
return false;
|
|
4146
|
+
}
|
|
4147
|
+
for (const k of ["read", "write"]) {
|
|
4148
|
+
const v = cache[k];
|
|
4149
|
+
if (v !== void 0 && !isFiniteNumber3(v)) {
|
|
4150
|
+
return false;
|
|
4151
|
+
}
|
|
4152
|
+
}
|
|
4153
|
+
}
|
|
4154
|
+
return true;
|
|
4155
|
+
}
|
|
4156
|
+
function usageFromModernMessage(value, fallbackSessionId, fallbackTimestampMs) {
|
|
4157
|
+
const model = value["model"];
|
|
4158
|
+
if (!isObject3(model)) {
|
|
4159
|
+
return void 0;
|
|
4160
|
+
}
|
|
4161
|
+
const providerId = model["providerID"];
|
|
4162
|
+
const modelId3 = model["modelID"] ?? model["id"];
|
|
4163
|
+
if (typeof providerId !== "string" || typeof modelId3 !== "string") {
|
|
4164
|
+
return void 0;
|
|
4165
|
+
}
|
|
4166
|
+
const tokens = value["tokens"];
|
|
4167
|
+
if (!isOpenCodeTokens(tokens)) {
|
|
4168
|
+
return void 0;
|
|
4169
|
+
}
|
|
4170
|
+
const time = value["time"];
|
|
4171
|
+
const messageTimestampMs = isObject3(time) ? timestampMs(time["created"] ?? time["completed"]) : void 0;
|
|
4172
|
+
const sessionId = typeof value["sessionID"] === "string" ? value["sessionID"] : fallbackSessionId;
|
|
4173
|
+
const tsMs = messageTimestampMs ?? fallbackTimestampMs;
|
|
4174
|
+
if (sessionId === void 0 || tsMs === void 0) {
|
|
4175
|
+
return void 0;
|
|
4176
|
+
}
|
|
4177
|
+
return {
|
|
4178
|
+
sessionId,
|
|
4179
|
+
providerId,
|
|
4180
|
+
modelId: modelId3,
|
|
4181
|
+
timestampMs: tsMs,
|
|
4182
|
+
tokens
|
|
4183
|
+
};
|
|
4184
|
+
}
|
|
4185
|
+
function usageFromLegacyMessage(value, fallbackSessionId, fallbackTimestampMs) {
|
|
4186
|
+
if (value["role"] !== "assistant") {
|
|
4187
|
+
return void 0;
|
|
4188
|
+
}
|
|
4189
|
+
const providerId = value["providerID"];
|
|
4190
|
+
const modelId3 = value["modelID"];
|
|
4191
|
+
const tokens = value["tokens"];
|
|
4192
|
+
if (typeof providerId !== "string" || typeof modelId3 !== "string" || !isOpenCodeTokens(tokens)) {
|
|
4193
|
+
return void 0;
|
|
4194
|
+
}
|
|
4195
|
+
const time = value["time"];
|
|
4196
|
+
const messageTimestampMs = isObject3(time) ? timestampMs(time["created"] ?? time["completed"]) : void 0;
|
|
4197
|
+
const sessionId = typeof value["sessionID"] === "string" ? value["sessionID"] : fallbackSessionId;
|
|
4198
|
+
const tsMs = messageTimestampMs ?? fallbackTimestampMs;
|
|
4199
|
+
if (sessionId === void 0 || tsMs === void 0) {
|
|
4200
|
+
return void 0;
|
|
4201
|
+
}
|
|
4202
|
+
return {
|
|
4203
|
+
sessionId,
|
|
4204
|
+
providerId,
|
|
4205
|
+
modelId: modelId3,
|
|
4206
|
+
timestampMs: tsMs,
|
|
4207
|
+
tokens
|
|
4208
|
+
};
|
|
4209
|
+
}
|
|
4210
|
+
function usageFromMetadataMessage(value, fallbackSessionId, fallbackTimestampMs) {
|
|
4211
|
+
if (value["role"] !== "assistant") {
|
|
4212
|
+
return void 0;
|
|
4213
|
+
}
|
|
4214
|
+
const metadata = value["metadata"];
|
|
4215
|
+
if (!isObject3(metadata)) {
|
|
4216
|
+
return void 0;
|
|
4217
|
+
}
|
|
4218
|
+
const assistant = metadata["assistant"];
|
|
4219
|
+
if (!isObject3(assistant)) {
|
|
4220
|
+
return void 0;
|
|
4221
|
+
}
|
|
4222
|
+
const providerId = assistant["providerID"];
|
|
4223
|
+
const modelId3 = assistant["modelID"];
|
|
4224
|
+
const tokens = assistant["tokens"];
|
|
4225
|
+
if (typeof providerId !== "string" || typeof modelId3 !== "string" || !isOpenCodeTokens(tokens)) {
|
|
4226
|
+
return void 0;
|
|
4227
|
+
}
|
|
4228
|
+
const time = metadata["time"];
|
|
4229
|
+
const messageTimestampMs = isObject3(time) ? timestampMs(time["created"] ?? time["completed"]) : void 0;
|
|
4230
|
+
const sessionId = typeof metadata["sessionID"] === "string" ? metadata["sessionID"] : fallbackSessionId;
|
|
4231
|
+
const tsMs = messageTimestampMs ?? fallbackTimestampMs;
|
|
4232
|
+
if (sessionId === void 0 || tsMs === void 0) {
|
|
4233
|
+
return void 0;
|
|
4234
|
+
}
|
|
4235
|
+
return {
|
|
4236
|
+
sessionId,
|
|
4237
|
+
providerId,
|
|
4238
|
+
modelId: modelId3,
|
|
4239
|
+
timestampMs: tsMs,
|
|
4240
|
+
tokens
|
|
4241
|
+
};
|
|
4242
|
+
}
|
|
4243
|
+
function pickOpenCodeUsage(value, fallbackSessionId, fallbackTimestampMs) {
|
|
4244
|
+
if (!isObject3(value)) {
|
|
4245
|
+
return void 0;
|
|
4246
|
+
}
|
|
4247
|
+
return usageFromModernMessage(value, fallbackSessionId, fallbackTimestampMs) ?? usageFromLegacyMessage(value, fallbackSessionId, fallbackTimestampMs) ?? usageFromMetadataMessage(value, fallbackSessionId, fallbackTimestampMs);
|
|
4248
|
+
}
|
|
4249
|
+
|
|
4250
|
+
// ../../packages/parsers/src/opencode/bucketize.ts
|
|
4251
|
+
var NODE_SQLITE_SPECIFIER = ["node", "sqlite"].join(":");
|
|
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
|
+
async function loadDatabaseSync() {
|
|
4335
|
+
const sqliteModule = await import(NODE_SQLITE_SPECIFIER);
|
|
4336
|
+
return sqliteModule.DatabaseSync;
|
|
4337
|
+
}
|
|
4338
|
+
function* readSessionMessageRows(db, cutoff) {
|
|
4339
|
+
const statement = db.prepare(`
|
|
4340
|
+
select session_id as "sessionId", time_created as "timeCreated", data
|
|
4341
|
+
from session_message
|
|
4342
|
+
where type = 'assistant' and time_created >= ?
|
|
4343
|
+
order by time_created asc, id asc
|
|
4344
|
+
`);
|
|
4345
|
+
yield* statement.all(cutoff.getTime());
|
|
4346
|
+
}
|
|
4347
|
+
async function* bucketizeOpenCodeDatabase(path2, cutoff, logger) {
|
|
4348
|
+
const accumulators = /* @__PURE__ */ new Map();
|
|
4349
|
+
const DatabaseSync = await loadDatabaseSync();
|
|
4350
|
+
let db;
|
|
4351
|
+
try {
|
|
4352
|
+
db = new DatabaseSync(path2, { readOnly: true, timeout: 1e3 });
|
|
4353
|
+
for (const row of readSessionMessageRows(db, cutoff)) {
|
|
4354
|
+
const sessionId = typeof row.sessionId === "string" ? row.sessionId : void 0;
|
|
4355
|
+
const fallbackTimestampMs = finiteTimestampMs(row.timeCreated);
|
|
4356
|
+
let parsed;
|
|
4357
|
+
try {
|
|
4358
|
+
parsed = parseJson(row.data);
|
|
4359
|
+
} catch {
|
|
4360
|
+
logger.warn("malformed opencode sqlite message", { path: path2 });
|
|
4361
|
+
continue;
|
|
4362
|
+
}
|
|
4363
|
+
const usage = pickOpenCodeUsage(parsed, sessionId, fallbackTimestampMs);
|
|
4364
|
+
if (usage !== void 0) {
|
|
4365
|
+
addUsage(accumulators, usage);
|
|
4366
|
+
}
|
|
4367
|
+
}
|
|
4368
|
+
} catch (err) {
|
|
4369
|
+
if (!isMissingTableError(err)) {
|
|
4370
|
+
logger.warn("failed to parse opencode sqlite database", { path: path2 });
|
|
4371
|
+
}
|
|
4372
|
+
} finally {
|
|
4373
|
+
db?.close();
|
|
4374
|
+
}
|
|
4375
|
+
yield* finalizedBuckets(accumulators);
|
|
4376
|
+
}
|
|
4377
|
+
async function* bucketizeOpenCodeJsonFile(path2, logger) {
|
|
4378
|
+
let parsed;
|
|
4379
|
+
try {
|
|
4380
|
+
parsed = JSON.parse(await readFile(path2, "utf8"));
|
|
4381
|
+
} catch {
|
|
4382
|
+
logger.warn("malformed opencode json file", { path: path2 });
|
|
4383
|
+
return;
|
|
4384
|
+
}
|
|
4385
|
+
const usage = pickOpenCodeUsage(parsed);
|
|
4386
|
+
if (usage === void 0) {
|
|
4387
|
+
return;
|
|
4388
|
+
}
|
|
4389
|
+
const accumulators = /* @__PURE__ */ new Map();
|
|
4390
|
+
addUsage(accumulators, usage);
|
|
4391
|
+
yield* finalizedBuckets(accumulators);
|
|
4392
|
+
}
|
|
4393
|
+
|
|
4394
|
+
// ../../packages/parsers/src/opencode/index.ts
|
|
4395
|
+
var OPENCODE_DB_FILE_PATTERN = /^opencode(?:-[^/]+)?\.db$/u;
|
|
4396
|
+
async function pathKind(path2) {
|
|
4397
|
+
try {
|
|
4398
|
+
const s = await stat4(path2);
|
|
4399
|
+
if (s.isFile()) {
|
|
4400
|
+
return "file";
|
|
4401
|
+
}
|
|
4402
|
+
if (s.isDirectory()) {
|
|
4403
|
+
return "directory";
|
|
4404
|
+
}
|
|
4405
|
+
return "missing";
|
|
4406
|
+
} catch {
|
|
4407
|
+
return "missing";
|
|
4408
|
+
}
|
|
4409
|
+
}
|
|
4410
|
+
function defaultDataRoot() {
|
|
4411
|
+
return readOpenCodeDataDir() ?? join4(homedir3(), ".local", "share", "opencode");
|
|
4412
|
+
}
|
|
4413
|
+
function resolveDefaultRoot() {
|
|
4414
|
+
const dbPath = readOpenCodeDbPath();
|
|
4415
|
+
if (dbPath === void 0) {
|
|
4416
|
+
return defaultDataRoot();
|
|
4417
|
+
}
|
|
4418
|
+
if (dbPath === ":memory:") {
|
|
4419
|
+
return dbPath;
|
|
4420
|
+
}
|
|
4421
|
+
if (isAbsolute(dbPath)) {
|
|
4422
|
+
return dbPath;
|
|
4423
|
+
}
|
|
4424
|
+
return join4(defaultDataRoot(), dbPath);
|
|
4425
|
+
}
|
|
4426
|
+
async function listOpenCodeDatabases(root) {
|
|
4427
|
+
let entries;
|
|
4428
|
+
try {
|
|
4429
|
+
entries = await readdir2(root, { withFileTypes: true });
|
|
4430
|
+
} catch {
|
|
4431
|
+
return [];
|
|
4432
|
+
}
|
|
4433
|
+
return entries.filter((entry) => entry.isFile() && OPENCODE_DB_FILE_PATTERN.test(String(entry.name))).map((entry) => join4(root, String(entry.name)));
|
|
4434
|
+
}
|
|
4435
|
+
async function listProjectLegacyRoots(root) {
|
|
4436
|
+
const projectRoot = join4(root, "project");
|
|
4437
|
+
let entries;
|
|
4438
|
+
try {
|
|
4439
|
+
entries = await readdir2(projectRoot, { withFileTypes: true });
|
|
4440
|
+
} catch {
|
|
4441
|
+
return [];
|
|
4442
|
+
}
|
|
4443
|
+
return entries.filter((entry) => entry.isDirectory()).flatMap((entry) => [
|
|
4444
|
+
join4(projectRoot, String(entry.name), "storage", "message"),
|
|
4445
|
+
join4(projectRoot, String(entry.name), "storage", "session", "message")
|
|
4446
|
+
]);
|
|
4447
|
+
}
|
|
4448
|
+
async function legacyRoots(root) {
|
|
4449
|
+
return [
|
|
4450
|
+
join4(root, "storage", "message"),
|
|
4451
|
+
join4(root, "storage", "session", "message"),
|
|
4452
|
+
...await listProjectLegacyRoots(root)
|
|
4453
|
+
];
|
|
4454
|
+
}
|
|
4455
|
+
async function* walkJson(root, cutoff) {
|
|
4456
|
+
let entries;
|
|
4457
|
+
try {
|
|
4458
|
+
entries = await readdir2(root, { withFileTypes: true });
|
|
4459
|
+
} catch {
|
|
4460
|
+
return;
|
|
4461
|
+
}
|
|
4462
|
+
for (const entry of entries) {
|
|
4463
|
+
const full = join4(root, String(entry.name));
|
|
4464
|
+
if (entry.isDirectory()) {
|
|
4465
|
+
yield* walkJson(full, cutoff);
|
|
4466
|
+
continue;
|
|
4467
|
+
}
|
|
4468
|
+
if (!(entry.isFile() && entry.name.endsWith(".json"))) {
|
|
4469
|
+
continue;
|
|
4470
|
+
}
|
|
4471
|
+
let mtime;
|
|
4472
|
+
try {
|
|
4473
|
+
({ mtime } = await stat4(full));
|
|
4474
|
+
} catch {
|
|
4475
|
+
continue;
|
|
4476
|
+
}
|
|
4477
|
+
if (mtime.getTime() >= cutoff.getTime()) {
|
|
4478
|
+
yield full;
|
|
4479
|
+
}
|
|
4480
|
+
}
|
|
4481
|
+
}
|
|
4482
|
+
async function* parseOpenCode(opts) {
|
|
4483
|
+
const logger = opts.logger ?? consoleLogger;
|
|
4484
|
+
const root = opts.root ?? resolveDefaultRoot();
|
|
4485
|
+
const kind = await pathKind(root);
|
|
4486
|
+
if (kind === "missing") {
|
|
4487
|
+
return;
|
|
4488
|
+
}
|
|
4489
|
+
if (kind === "file") {
|
|
4490
|
+
if (basename(root).endsWith(".json")) {
|
|
4491
|
+
yield* bucketizeOpenCodeJsonFile(root, logger);
|
|
4492
|
+
return;
|
|
4493
|
+
}
|
|
4494
|
+
yield* bucketizeOpenCodeDatabase(root, opts.cutoff, logger);
|
|
4495
|
+
return;
|
|
4496
|
+
}
|
|
4497
|
+
const databases = await listOpenCodeDatabases(root);
|
|
4498
|
+
if (databases.length > 0) {
|
|
4499
|
+
for (const dbPath of databases) {
|
|
4500
|
+
yield* bucketizeOpenCodeDatabase(dbPath, opts.cutoff, logger);
|
|
4501
|
+
}
|
|
4502
|
+
return;
|
|
4503
|
+
}
|
|
4504
|
+
for (const legacyRoot of await legacyRoots(root)) {
|
|
4505
|
+
for await (const file of walkJson(legacyRoot, opts.cutoff)) {
|
|
4506
|
+
yield* bucketizeOpenCodeJsonFile(file, logger);
|
|
4507
|
+
}
|
|
4508
|
+
}
|
|
4509
|
+
}
|
|
4510
|
+
|
|
4511
|
+
// ../../packages/parsers/src/pi/index.ts
|
|
4512
|
+
init_esm_shims();
|
|
4513
|
+
import { stat as stat5 } from "fs/promises";
|
|
4514
|
+
import { homedir as homedir4 } from "os";
|
|
4515
|
+
import { join as join5 } from "path";
|
|
4098
4516
|
|
|
4099
4517
|
// ../../packages/parsers/src/pi/bucketize.ts
|
|
4100
4518
|
init_esm_shims();
|
|
@@ -4103,27 +4521,27 @@ import { createInterface as createInterface3 } from "readline";
|
|
|
4103
4521
|
|
|
4104
4522
|
// ../../packages/parsers/src/pi/events.ts
|
|
4105
4523
|
init_esm_shims();
|
|
4106
|
-
function
|
|
4524
|
+
function isObject4(value) {
|
|
4107
4525
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
4108
4526
|
}
|
|
4109
|
-
function
|
|
4527
|
+
function isFiniteNumber4(value) {
|
|
4110
4528
|
return typeof value === "number" && Number.isFinite(value);
|
|
4111
4529
|
}
|
|
4112
4530
|
function isPiUsage(value) {
|
|
4113
|
-
if (!
|
|
4531
|
+
if (!isObject4(value)) {
|
|
4114
4532
|
return false;
|
|
4115
4533
|
}
|
|
4116
4534
|
const keys = ["input", "output", "cacheRead", "cacheWrite"];
|
|
4117
4535
|
for (const k of keys) {
|
|
4118
4536
|
const v = value[k];
|
|
4119
|
-
if (v !== void 0 && !
|
|
4537
|
+
if (v !== void 0 && !isFiniteNumber4(v)) {
|
|
4120
4538
|
return false;
|
|
4121
4539
|
}
|
|
4122
4540
|
}
|
|
4123
4541
|
return true;
|
|
4124
4542
|
}
|
|
4125
4543
|
function isPiAssistantMessageEntry(value) {
|
|
4126
|
-
if (!
|
|
4544
|
+
if (!isObject4(value)) {
|
|
4127
4545
|
return false;
|
|
4128
4546
|
}
|
|
4129
4547
|
if (value["type"] !== "message") {
|
|
@@ -4133,7 +4551,7 @@ function isPiAssistantMessageEntry(value) {
|
|
|
4133
4551
|
return false;
|
|
4134
4552
|
}
|
|
4135
4553
|
const message = value["message"];
|
|
4136
|
-
if (!
|
|
4554
|
+
if (!isObject4(message)) {
|
|
4137
4555
|
return false;
|
|
4138
4556
|
}
|
|
4139
4557
|
if (message["role"] !== "assistant") {
|
|
@@ -4148,7 +4566,7 @@ function isPiAssistantMessageEntry(value) {
|
|
|
4148
4566
|
if (message["stopReason"] !== void 0 && typeof message["stopReason"] !== "string") {
|
|
4149
4567
|
return false;
|
|
4150
4568
|
}
|
|
4151
|
-
if (message["timestamp"] !== void 0 && !
|
|
4569
|
+
if (message["timestamp"] !== void 0 && !isFiniteNumber4(message["timestamp"])) {
|
|
4152
4570
|
return false;
|
|
4153
4571
|
}
|
|
4154
4572
|
if (!isPiUsage(message["usage"])) {
|
|
@@ -4158,7 +4576,7 @@ function isPiAssistantMessageEntry(value) {
|
|
|
4158
4576
|
}
|
|
4159
4577
|
|
|
4160
4578
|
// ../../packages/parsers/src/pi/bucketize.ts
|
|
4161
|
-
function
|
|
4579
|
+
function key4(hourUtc, model) {
|
|
4162
4580
|
return `${hourUtc.toISOString()}|${model}`;
|
|
4163
4581
|
}
|
|
4164
4582
|
function eventTimestampMs(entry) {
|
|
@@ -4167,7 +4585,7 @@ function eventTimestampMs(entry) {
|
|
|
4167
4585
|
}
|
|
4168
4586
|
return Date.parse(entry.timestamp);
|
|
4169
4587
|
}
|
|
4170
|
-
function
|
|
4588
|
+
function modelId2(provider, model) {
|
|
4171
4589
|
const trimmedProvider = provider.trim();
|
|
4172
4590
|
const trimmedModel = model.trim();
|
|
4173
4591
|
if (trimmedProvider.length === 0 || trimmedModel.length === 0) {
|
|
@@ -4206,7 +4624,7 @@ async function* bucketizePiStyleFile(path2, harness, logger) {
|
|
|
4206
4624
|
if (!Number.isFinite(tsMs)) {
|
|
4207
4625
|
continue;
|
|
4208
4626
|
}
|
|
4209
|
-
const model =
|
|
4627
|
+
const model = modelId2(parsed.message.provider, parsed.message.model);
|
|
4210
4628
|
if (model === void 0) {
|
|
4211
4629
|
continue;
|
|
4212
4630
|
}
|
|
@@ -4226,7 +4644,7 @@ async function* bucketizePiStyleFile(path2, harness, logger) {
|
|
|
4226
4644
|
sessionLastSeenAt = eventAt;
|
|
4227
4645
|
}
|
|
4228
4646
|
const hourUtc = startOfUtcHour(eventAt);
|
|
4229
|
-
const k =
|
|
4647
|
+
const k = key4(hourUtc, model);
|
|
4230
4648
|
const existing = buckets.get(k);
|
|
4231
4649
|
if (existing === void 0) {
|
|
4232
4650
|
buckets.set(k, {
|
|
@@ -4271,7 +4689,7 @@ async function* bucketizePiStyleFile(path2, harness, logger) {
|
|
|
4271
4689
|
// ../../packages/parsers/src/pi/index.ts
|
|
4272
4690
|
async function isFile3(path2) {
|
|
4273
4691
|
try {
|
|
4274
|
-
return (await
|
|
4692
|
+
return (await stat5(path2)).isFile();
|
|
4275
4693
|
} catch {
|
|
4276
4694
|
return false;
|
|
4277
4695
|
}
|
|
@@ -4281,14 +4699,14 @@ function defaultPiRoot() {
|
|
|
4281
4699
|
if (sessionDir !== void 0) {
|
|
4282
4700
|
return sessionDir;
|
|
4283
4701
|
}
|
|
4284
|
-
return
|
|
4702
|
+
return join5(readPiAgentDir() ?? join5(homedir4(), ".pi", "agent"), "sessions");
|
|
4285
4703
|
}
|
|
4286
4704
|
function defaultHermesRoot() {
|
|
4287
4705
|
const sessionDir = readHermesSessionDir();
|
|
4288
4706
|
if (sessionDir !== void 0) {
|
|
4289
4707
|
return sessionDir;
|
|
4290
4708
|
}
|
|
4291
|
-
return
|
|
4709
|
+
return join5(readHermesAgentDir() ?? join5(homedir4(), ".hermes", "agent"), "sessions");
|
|
4292
4710
|
}
|
|
4293
4711
|
async function* parsePiStyle(opts, harness, defaultRoot2) {
|
|
4294
4712
|
const logger = opts.logger ?? consoleLogger;
|
|
@@ -4309,29 +4727,69 @@ async function* parseHermes(opts) {
|
|
|
4309
4727
|
}
|
|
4310
4728
|
|
|
4311
4729
|
// src/sync/parser-factory.ts
|
|
4730
|
+
var OPENCODE_DB_FILE_PATTERN2 = /^opencode(?:-[^/]+)?\.db$/u;
|
|
4312
4731
|
function sessionsRoot(agentDir, sessionDir, fallbackAgentDir) {
|
|
4313
|
-
return sessionDir ??
|
|
4732
|
+
return sessionDir ?? join6(agentDir ?? fallbackAgentDir, "sessions");
|
|
4733
|
+
}
|
|
4734
|
+
function isFile4(path2) {
|
|
4735
|
+
try {
|
|
4736
|
+
return statSync(path2).isFile();
|
|
4737
|
+
} catch {
|
|
4738
|
+
return false;
|
|
4739
|
+
}
|
|
4740
|
+
}
|
|
4741
|
+
function defaultOpenCodeDataRoot(home) {
|
|
4742
|
+
return join6(home, ".local", "share", "opencode");
|
|
4743
|
+
}
|
|
4744
|
+
function openCodeRoot(home, env) {
|
|
4745
|
+
const dataRoot = env.opencodeDataDir ?? defaultOpenCodeDataRoot(home);
|
|
4746
|
+
const dbPath = env.opencodeDbPath;
|
|
4747
|
+
if (dbPath === void 0 || dbPath === ":memory:") {
|
|
4748
|
+
return dbPath ?? dataRoot;
|
|
4749
|
+
}
|
|
4750
|
+
return isAbsolute2(dbPath) ? dbPath : join6(dataRoot, dbPath);
|
|
4751
|
+
}
|
|
4752
|
+
function hasOpenCodeDatabase(root) {
|
|
4753
|
+
let entries;
|
|
4754
|
+
try {
|
|
4755
|
+
entries = readdirSync(root);
|
|
4756
|
+
} catch {
|
|
4757
|
+
return false;
|
|
4758
|
+
}
|
|
4759
|
+
return entries.some((entry) => OPENCODE_DB_FILE_PATTERN2.test(entry) && isFile4(join6(root, entry)));
|
|
4760
|
+
}
|
|
4761
|
+
function openCodeSourceExists(root) {
|
|
4762
|
+
if (root === ":memory:") {
|
|
4763
|
+
return false;
|
|
4764
|
+
}
|
|
4765
|
+
if (isFile4(root)) {
|
|
4766
|
+
return true;
|
|
4767
|
+
}
|
|
4768
|
+
return hasOpenCodeDatabase(root) || existsSync(join6(root, "storage", "message")) || existsSync(join6(root, "storage", "session", "message")) || existsSync(join6(root, "project"));
|
|
4314
4769
|
}
|
|
4315
4770
|
function buildRealParserFactory() {
|
|
4316
4771
|
return (ctx) => {
|
|
4317
|
-
const home =
|
|
4772
|
+
const home = homedir5();
|
|
4318
4773
|
const env = readCliEnv();
|
|
4319
|
-
const codexSessionsRoot =
|
|
4320
|
-
const codexArchivedRoot =
|
|
4774
|
+
const codexSessionsRoot = join6(home, ".codex", "sessions");
|
|
4775
|
+
const codexArchivedRoot = join6(home, ".codex", "archived_sessions");
|
|
4321
4776
|
const codexExists = existsSync(codexSessionsRoot) || existsSync(codexArchivedRoot);
|
|
4322
4777
|
const envDir = env.claudeConfigDir;
|
|
4323
|
-
const claudeRoot = envDir == null ?
|
|
4778
|
+
const claudeRoot = envDir == null ? join6(home, ".claude", "projects") : join6(envDir, "projects");
|
|
4324
4779
|
const claudeExists = existsSync(claudeRoot);
|
|
4325
|
-
const piRoot = sessionsRoot(env.piAgentDir, env.piSessionDir,
|
|
4780
|
+
const piRoot = sessionsRoot(env.piAgentDir, env.piSessionDir, join6(home, ".pi", "agent"));
|
|
4326
4781
|
const piExists = existsSync(piRoot);
|
|
4327
|
-
const hermesRoot = sessionsRoot(env.hermesAgentDir, env.hermesSessionDir,
|
|
4782
|
+
const hermesRoot = sessionsRoot(env.hermesAgentDir, env.hermesSessionDir, join6(home, ".hermes", "agent"));
|
|
4328
4783
|
const hermesExists = existsSync(hermesRoot);
|
|
4784
|
+
const opencodeRoot = openCodeRoot(home, env);
|
|
4785
|
+
const opencodeExists = openCodeSourceExists(opencodeRoot);
|
|
4329
4786
|
return {
|
|
4330
|
-
anySourceExisted: codexExists || claudeExists || piExists || hermesExists,
|
|
4787
|
+
anySourceExisted: codexExists || claudeExists || piExists || hermesExists || opencodeExists,
|
|
4331
4788
|
codex: parseCodex({ cutoff: ctx.cutoff }),
|
|
4332
4789
|
claudeCode: parseClaude({ cutoff: ctx.cutoff, root: claudeRoot }),
|
|
4333
4790
|
pi: parsePi({ cutoff: ctx.cutoff, root: piRoot }),
|
|
4334
|
-
hermes: parseHermes({ cutoff: ctx.cutoff, root: hermesRoot })
|
|
4791
|
+
hermes: parseHermes({ cutoff: ctx.cutoff, root: hermesRoot }),
|
|
4792
|
+
opencode: parseOpenCode({ cutoff: ctx.cutoff, root: opencodeRoot })
|
|
4335
4793
|
};
|
|
4336
4794
|
};
|
|
4337
4795
|
}
|
|
@@ -4345,7 +4803,7 @@ import { createHmac } from "crypto";
|
|
|
4345
4803
|
function toIso(hourUtc) {
|
|
4346
4804
|
return hourUtc instanceof Date ? hourUtc.toISOString() : hourUtc;
|
|
4347
4805
|
}
|
|
4348
|
-
function
|
|
4806
|
+
function key5(b) {
|
|
4349
4807
|
return `${b.harness} ${b.model} ${toIso(b.hourUtc)}`;
|
|
4350
4808
|
}
|
|
4351
4809
|
function finalize(acc) {
|
|
@@ -4402,7 +4860,7 @@ async function* aggregateUsage(source, options) {
|
|
|
4402
4860
|
const accumulators = /* @__PURE__ */ new Map();
|
|
4403
4861
|
const sessionAccumulators = /* @__PURE__ */ new Map();
|
|
4404
4862
|
for await (const bucket of source) {
|
|
4405
|
-
const k =
|
|
4863
|
+
const k = key5(bucket);
|
|
4406
4864
|
let acc = accumulators.get(k);
|
|
4407
4865
|
if (!acc) {
|
|
4408
4866
|
acc = {
|
|
@@ -4461,11 +4919,11 @@ var __commonJS2 = (cb, mod) => function() {
|
|
|
4461
4919
|
return mod || (0, cb[__getOwnPropNames2(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
4462
4920
|
};
|
|
4463
4921
|
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,
|
|
4922
|
+
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames2(from), i = 0, n = keys.length, key6; i < n; i++) {
|
|
4923
|
+
key6 = keys[i];
|
|
4924
|
+
if (!__hasOwnProp2.call(to, key6) && key6 !== except) __defProp2(to, key6, {
|
|
4925
|
+
get: ((k) => from[k]).bind(null, key6),
|
|
4926
|
+
enumerable: !(desc = __getOwnPropDesc2(from, key6)) || desc.enumerable
|
|
4469
4927
|
});
|
|
4470
4928
|
}
|
|
4471
4929
|
return to;
|
|
@@ -4740,7 +5198,7 @@ init_esm_shims();
|
|
|
4740
5198
|
|
|
4741
5199
|
// ../../node_modules/.pnpm/@trpc+server@11.17.0_typescript@6.0.3/node_modules/@trpc/server/dist/codes-DagpWZLc.mjs
|
|
4742
5200
|
init_esm_shims();
|
|
4743
|
-
function
|
|
5201
|
+
function isObject5(value) {
|
|
4744
5202
|
return !!value && !Array.isArray(value) && typeof value === "object";
|
|
4745
5203
|
}
|
|
4746
5204
|
function emptyObject() {
|
|
@@ -4787,11 +5245,11 @@ var __commonJS3 = (cb, mod) => function() {
|
|
|
4787
5245
|
return mod || (0, cb[__getOwnPropNames3(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
4788
5246
|
};
|
|
4789
5247
|
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,
|
|
5248
|
+
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames3(from), i = 0, n = keys.length, key6; i < n; i++) {
|
|
5249
|
+
key6 = keys[i];
|
|
5250
|
+
if (!__hasOwnProp3.call(to, key6) && key6 !== except) __defProp3(to, key6, {
|
|
5251
|
+
get: ((k) => from[k]).bind(null, key6),
|
|
5252
|
+
enumerable: !(desc = __getOwnPropDesc3(from, key6)) || desc.enumerable
|
|
4795
5253
|
});
|
|
4796
5254
|
}
|
|
4797
5255
|
return to;
|
|
@@ -4809,9 +5267,9 @@ function createInnerProxy(callback, path2, memo) {
|
|
|
4809
5267
|
var _memo$cacheKey;
|
|
4810
5268
|
const cacheKey = path2.join(".");
|
|
4811
5269
|
(_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,
|
|
5270
|
+
get(_obj, key6) {
|
|
5271
|
+
if (typeof key6 !== "string" || key6 === "then") return void 0;
|
|
5272
|
+
return createInnerProxy(callback, [...path2, key6], memo);
|
|
4815
5273
|
},
|
|
4816
5274
|
apply(_1, _2, args) {
|
|
4817
5275
|
const lastOfPath = path2[path2.length - 1];
|
|
@@ -4951,8 +5409,8 @@ function transformResult(response, transformer) {
|
|
|
4951
5409
|
} catch (_unused) {
|
|
4952
5410
|
throw new TransformResultError();
|
|
4953
5411
|
}
|
|
4954
|
-
if (!result.ok && (!
|
|
4955
|
-
if (result.ok && !
|
|
5412
|
+
if (!result.ok && (!isObject5(result.error.error) || typeof result.error.error["code"] !== "number")) throw new TransformResultError();
|
|
5413
|
+
if (result.ok && !isObject5(result.result)) throw new TransformResultError();
|
|
4956
5414
|
return result;
|
|
4957
5415
|
}
|
|
4958
5416
|
var import_objectSpread22 = __toESM3(require_objectSpread22(), 1);
|
|
@@ -4964,11 +5422,11 @@ function isTRPCClientError(cause) {
|
|
|
4964
5422
|
return cause instanceof TRPCClientError;
|
|
4965
5423
|
}
|
|
4966
5424
|
function isTRPCErrorResponse(obj) {
|
|
4967
|
-
return
|
|
5425
|
+
return isObject5(obj) && isObject5(obj["error"]) && typeof obj["error"]["code"] === "number" && typeof obj["error"]["message"] === "string";
|
|
4968
5426
|
}
|
|
4969
5427
|
function getMessageFromUnknownError(err, fallback) {
|
|
4970
5428
|
if (typeof err === "string") return err;
|
|
4971
|
-
if (
|
|
5429
|
+
if (isObject5(err) && typeof err["message"] === "string") return err["message"];
|
|
4972
5430
|
return fallback;
|
|
4973
5431
|
}
|
|
4974
5432
|
var TRPCClientError = class TRPCClientError2 extends Error {
|
|
@@ -5213,11 +5671,11 @@ function dataLoader(batchLoader) {
|
|
|
5213
5671
|
});
|
|
5214
5672
|
}
|
|
5215
5673
|
}
|
|
5216
|
-
function load(
|
|
5674
|
+
function load(key6) {
|
|
5217
5675
|
var _dispatchTimer;
|
|
5218
5676
|
const item = {
|
|
5219
5677
|
aborted: false,
|
|
5220
|
-
key:
|
|
5678
|
+
key: key6,
|
|
5221
5679
|
batch: null,
|
|
5222
5680
|
resolve: throwFatalError,
|
|
5223
5681
|
reject: throwFatalError
|
|
@@ -5592,9 +6050,9 @@ function createTRPCClientProxy(client) {
|
|
|
5592
6050
|
const fullPath = pathCopy.join(".");
|
|
5593
6051
|
return client[procedureType](fullPath, ...args);
|
|
5594
6052
|
});
|
|
5595
|
-
return createFlatProxy((
|
|
5596
|
-
if (
|
|
5597
|
-
return proxy[
|
|
6053
|
+
return createFlatProxy((key6) => {
|
|
6054
|
+
if (key6 === untypedClientSymbol) return client;
|
|
6055
|
+
return proxy[key6];
|
|
5598
6056
|
});
|
|
5599
6057
|
}
|
|
5600
6058
|
function createTRPCClient(opts) {
|
|
@@ -5860,6 +6318,9 @@ async function runSync(options) {
|
|
|
5860
6318
|
if (options.harness === void 0 || options.harness === "hermes") {
|
|
5861
6319
|
sources.push({ label: "Hermes", source: parsers.hermes });
|
|
5862
6320
|
}
|
|
6321
|
+
if (options.harness === void 0 || options.harness === "opencode") {
|
|
6322
|
+
sources.push({ label: "OpenCode", source: parsers.opencode });
|
|
6323
|
+
}
|
|
5863
6324
|
let bucketsUploaded = 0;
|
|
5864
6325
|
let sessionsUploaded = 0;
|
|
5865
6326
|
let batchesUploaded = 0;
|
|
@@ -6034,7 +6495,7 @@ function readPackageVersion() {
|
|
|
6034
6495
|
return "0.0.0";
|
|
6035
6496
|
}
|
|
6036
6497
|
var VERSION = readPackageVersion();
|
|
6037
|
-
var SUPPORTED_HARNESSES = ["codex", "claude_code", "pi", "hermes"];
|
|
6498
|
+
var SUPPORTED_HARNESSES = ["codex", "claude_code", "pi", "hermes", "opencode"];
|
|
6038
6499
|
function writeStdoutLine(msg) {
|
|
6039
6500
|
process4.stdout.write(`${msg}
|
|
6040
6501
|
`);
|
|
@@ -6068,7 +6529,7 @@ function buildCli() {
|
|
|
6068
6529
|
const env = readCliEnv();
|
|
6069
6530
|
const program2 = new Command();
|
|
6070
6531
|
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
|
|
6532
|
+
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
6533
|
async (raw) => {
|
|
6073
6534
|
const token = raw.token ?? env.token;
|
|
6074
6535
|
const device = raw.device ?? env.device;
|