iteration-cli 0.10.1 → 0.12.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/cli.js +1424 -300
- package/dist/cursor-hook-entry.js +209 -53
- package/dist/launcher.js +69 -0
- package/package.json +2 -2
|
@@ -932,8 +932,8 @@ var require_src = __commonJS({
|
|
|
932
932
|
|
|
933
933
|
// src/cursor-hook-entry.ts
|
|
934
934
|
import { randomUUID } from "node:crypto";
|
|
935
|
-
import { promises as
|
|
936
|
-
import
|
|
935
|
+
import { promises as fs2 } from "node:fs";
|
|
936
|
+
import path4 from "node:path";
|
|
937
937
|
import { StringDecoder } from "node:string_decoder";
|
|
938
938
|
|
|
939
939
|
// ../../node_modules/.pnpm/zod@4.6.4/node_modules/zod/v4/core/util.js
|
|
@@ -1172,10 +1172,10 @@ function mergeDefs(...defs) {
|
|
|
1172
1172
|
function cloneDef(schema) {
|
|
1173
1173
|
return mergeDefs(schema._zod.def);
|
|
1174
1174
|
}
|
|
1175
|
-
function getElementAtPath(obj,
|
|
1176
|
-
if (!
|
|
1175
|
+
function getElementAtPath(obj, path5) {
|
|
1176
|
+
if (!path5)
|
|
1177
1177
|
return obj;
|
|
1178
|
-
return
|
|
1178
|
+
return path5.reduce((acc, key) => acc?.[key], obj);
|
|
1179
1179
|
}
|
|
1180
1180
|
function promiseAllObject(promisesObj) {
|
|
1181
1181
|
const keys = Object.keys(promisesObj);
|
|
@@ -1515,11 +1515,11 @@ function explicitlyAborted(x, startIndex = 0) {
|
|
|
1515
1515
|
}
|
|
1516
1516
|
return false;
|
|
1517
1517
|
}
|
|
1518
|
-
function prefixIssues(
|
|
1518
|
+
function prefixIssues(path5, issues) {
|
|
1519
1519
|
return issues.map((iss) => {
|
|
1520
1520
|
var _a3;
|
|
1521
1521
|
(_a3 = iss).path ?? (_a3.path = []);
|
|
1522
|
-
iss.path.unshift(
|
|
1522
|
+
iss.path.unshift(path5);
|
|
1523
1523
|
return iss;
|
|
1524
1524
|
});
|
|
1525
1525
|
}
|
|
@@ -1965,16 +1965,16 @@ function flattenError(error2, mapper = (issue2) => issue2.message) {
|
|
|
1965
1965
|
}
|
|
1966
1966
|
function formatError(error2, mapper = (issue2) => issue2.message) {
|
|
1967
1967
|
const fieldErrors = { _errors: [] };
|
|
1968
|
-
const processError = (error3,
|
|
1968
|
+
const processError = (error3, path5 = []) => {
|
|
1969
1969
|
for (const issue2 of error3.issues) {
|
|
1970
1970
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
1971
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
1971
|
+
issue2.errors.map((issues) => processError({ issues }, [...path5, ...issue2.path]));
|
|
1972
1972
|
} else if (issue2.code === "invalid_key") {
|
|
1973
|
-
processError({ issues: issue2.issues }, [...
|
|
1973
|
+
processError({ issues: issue2.issues }, [...path5, ...issue2.path]);
|
|
1974
1974
|
} else if (issue2.code === "invalid_element") {
|
|
1975
|
-
processError({ issues: issue2.issues }, [...
|
|
1975
|
+
processError({ issues: issue2.issues }, [...path5, ...issue2.path]);
|
|
1976
1976
|
} else {
|
|
1977
|
-
const fullpath = [...
|
|
1977
|
+
const fullpath = [...path5, ...issue2.path];
|
|
1978
1978
|
if (fullpath.length === 0) {
|
|
1979
1979
|
fieldErrors._errors.push(mapper(issue2));
|
|
1980
1980
|
} else {
|
|
@@ -7285,6 +7285,31 @@ function superRefine(fn, params) {
|
|
|
7285
7285
|
return _superRefine(fn, params);
|
|
7286
7286
|
}
|
|
7287
7287
|
|
|
7288
|
+
// ../../node_modules/.pnpm/zod@4.6.4/node_modules/zod/v4/classic/iso.js
|
|
7289
|
+
var iso_exports = {};
|
|
7290
|
+
__export(iso_exports, {
|
|
7291
|
+
ZodISODate: () => ZodISODate,
|
|
7292
|
+
ZodISODateTime: () => ZodISODateTime,
|
|
7293
|
+
ZodISODuration: () => ZodISODuration,
|
|
7294
|
+
ZodISOTime: () => ZodISOTime,
|
|
7295
|
+
date: () => date2,
|
|
7296
|
+
datetime: () => datetime2,
|
|
7297
|
+
duration: () => duration2,
|
|
7298
|
+
time: () => time2
|
|
7299
|
+
});
|
|
7300
|
+
function datetime2(params) {
|
|
7301
|
+
return _isoDateTime(ZodISODateTime, params);
|
|
7302
|
+
}
|
|
7303
|
+
function date2(params) {
|
|
7304
|
+
return _isoDate(ZodISODate, params);
|
|
7305
|
+
}
|
|
7306
|
+
function time2(params) {
|
|
7307
|
+
return _isoTime(ZodISOTime, params);
|
|
7308
|
+
}
|
|
7309
|
+
function duration2(params) {
|
|
7310
|
+
return _isoDuration(ZodISODuration, params);
|
|
7311
|
+
}
|
|
7312
|
+
|
|
7288
7313
|
// src/cursor-hooks.ts
|
|
7289
7314
|
import path2 from "node:path";
|
|
7290
7315
|
|
|
@@ -7321,6 +7346,47 @@ var TRACE_EVENT_TYPES = [
|
|
|
7321
7346
|
];
|
|
7322
7347
|
var COLLECTOR_SOURCES = ["codex", "claude", "cursor"];
|
|
7323
7348
|
var MAX_TRACE_EVENTS_PER_BATCH = 100;
|
|
7349
|
+
var cursorBillingRequestSchema = object({
|
|
7350
|
+
conversationId: uuid2(),
|
|
7351
|
+
reconcileFromMs: number2().int().nonnegative().nullable(),
|
|
7352
|
+
events: array(object({
|
|
7353
|
+
timestamp: number2().int().nonnegative(),
|
|
7354
|
+
kind: _enum([
|
|
7355
|
+
"included",
|
|
7356
|
+
"paid",
|
|
7357
|
+
"byok",
|
|
7358
|
+
"not_charged",
|
|
7359
|
+
"unknown"
|
|
7360
|
+
]),
|
|
7361
|
+
inputTokens: number2().int().nonnegative().nullable(),
|
|
7362
|
+
outputTokens: number2().int().nonnegative().nullable(),
|
|
7363
|
+
cacheReadTokens: number2().int().nonnegative().nullable(),
|
|
7364
|
+
cacheWriteTokens: number2().int().nonnegative().nullable(),
|
|
7365
|
+
paidUsd: number2().finite().nonnegative().nullable()
|
|
7366
|
+
}).strict()).max(5e3)
|
|
7367
|
+
}).strict();
|
|
7368
|
+
var codexBillingRequestSchema = object({
|
|
7369
|
+
accountFingerprint: string2().regex(/^[0-9a-f]{64}$/),
|
|
7370
|
+
reconcile: boolean2(),
|
|
7371
|
+
tasks: array(object({
|
|
7372
|
+
threadId: uuid2(),
|
|
7373
|
+
createdAt: iso_exports.datetime().nullable(),
|
|
7374
|
+
descendantThreadIds: array(uuid2()).max(900),
|
|
7375
|
+
dataStatus: _enum([
|
|
7376
|
+
"available",
|
|
7377
|
+
"partial",
|
|
7378
|
+
"unavailable",
|
|
7379
|
+
"not_queried"
|
|
7380
|
+
]),
|
|
7381
|
+
usageSource: string2().max(100),
|
|
7382
|
+
balanceUsageCredits: string2().regex(/^[+-]?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d{1,3})?$/).max(128).nullable()
|
|
7383
|
+
}).strict()).max(100),
|
|
7384
|
+
authTurns: array(object({
|
|
7385
|
+
threadId: uuid2(),
|
|
7386
|
+
turnId: uuid2(),
|
|
7387
|
+
mode: _enum(["chatgpt", "api_key", "conflicting"])
|
|
7388
|
+
}).strict()).max(5e3)
|
|
7389
|
+
}).strict();
|
|
7324
7390
|
var UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
7325
7391
|
var TIMESTAMP_PATTERN = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2})$/;
|
|
7326
7392
|
var unpairedSurrogate = /[\uD800-\uDFFF]/u;
|
|
@@ -8542,11 +8608,11 @@ function requireLodash_sortby() {
|
|
|
8542
8608
|
function baseForOwn(object2, iteratee) {
|
|
8543
8609
|
return object2 && baseFor(object2, iteratee, keys);
|
|
8544
8610
|
}
|
|
8545
|
-
function baseGet(object2,
|
|
8546
|
-
|
|
8547
|
-
var index = 0, length =
|
|
8611
|
+
function baseGet(object2, path5) {
|
|
8612
|
+
path5 = isKey(path5, object2) ? [path5] : castPath(path5);
|
|
8613
|
+
var index = 0, length = path5.length;
|
|
8548
8614
|
while (object2 != null && index < length) {
|
|
8549
|
-
object2 = object2[toKey(
|
|
8615
|
+
object2 = object2[toKey(path5[index++])];
|
|
8550
8616
|
}
|
|
8551
8617
|
return index && index == length ? object2 : void 0;
|
|
8552
8618
|
}
|
|
@@ -8673,13 +8739,13 @@ function requireLodash_sortby() {
|
|
|
8673
8739
|
return object2 === source || baseIsMatch(object2, source, matchData);
|
|
8674
8740
|
};
|
|
8675
8741
|
}
|
|
8676
|
-
function baseMatchesProperty(
|
|
8677
|
-
if (isKey(
|
|
8678
|
-
return matchesStrictComparable(toKey(
|
|
8742
|
+
function baseMatchesProperty(path5, srcValue) {
|
|
8743
|
+
if (isKey(path5) && isStrictComparable(srcValue)) {
|
|
8744
|
+
return matchesStrictComparable(toKey(path5), srcValue);
|
|
8679
8745
|
}
|
|
8680
8746
|
return function(object2) {
|
|
8681
|
-
var objValue = get(object2,
|
|
8682
|
-
return objValue === void 0 && objValue === srcValue ? hasIn(object2,
|
|
8747
|
+
var objValue = get(object2, path5);
|
|
8748
|
+
return objValue === void 0 && objValue === srcValue ? hasIn(object2, path5) : baseIsEqual(srcValue, objValue, void 0, UNORDERED_COMPARE_FLAG | PARTIAL_COMPARE_FLAG);
|
|
8683
8749
|
};
|
|
8684
8750
|
}
|
|
8685
8751
|
function baseOrderBy(collection, iteratees, orders) {
|
|
@@ -8695,9 +8761,9 @@ function requireLodash_sortby() {
|
|
|
8695
8761
|
return compareMultiple(object2, other, orders);
|
|
8696
8762
|
});
|
|
8697
8763
|
}
|
|
8698
|
-
function basePropertyDeep(
|
|
8764
|
+
function basePropertyDeep(path5) {
|
|
8699
8765
|
return function(object2) {
|
|
8700
|
-
return baseGet(object2,
|
|
8766
|
+
return baseGet(object2, path5);
|
|
8701
8767
|
};
|
|
8702
8768
|
}
|
|
8703
8769
|
function baseRest(func, start) {
|
|
@@ -8952,11 +9018,11 @@ function requireLodash_sortby() {
|
|
|
8952
9018
|
return result;
|
|
8953
9019
|
};
|
|
8954
9020
|
}
|
|
8955
|
-
function hasPath(object2,
|
|
8956
|
-
|
|
8957
|
-
var result, index = -1, length =
|
|
9021
|
+
function hasPath(object2, path5, hasFunc) {
|
|
9022
|
+
path5 = isKey(path5, object2) ? [path5] : castPath(path5);
|
|
9023
|
+
var result, index = -1, length = path5.length;
|
|
8958
9024
|
while (++index < length) {
|
|
8959
|
-
var key = toKey(
|
|
9025
|
+
var key = toKey(path5[index]);
|
|
8960
9026
|
if (!(result = object2 != null && hasFunc(object2, key))) {
|
|
8961
9027
|
break;
|
|
8962
9028
|
}
|
|
@@ -9111,12 +9177,12 @@ function requireLodash_sortby() {
|
|
|
9111
9177
|
function toString(value) {
|
|
9112
9178
|
return value == null ? "" : baseToString(value);
|
|
9113
9179
|
}
|
|
9114
|
-
function get(object2,
|
|
9115
|
-
var result = object2 == null ? void 0 : baseGet(object2,
|
|
9180
|
+
function get(object2, path5, defaultValue) {
|
|
9181
|
+
var result = object2 == null ? void 0 : baseGet(object2, path5);
|
|
9116
9182
|
return result === void 0 ? defaultValue : result;
|
|
9117
9183
|
}
|
|
9118
|
-
function hasIn(object2,
|
|
9119
|
-
return object2 != null && hasPath(object2,
|
|
9184
|
+
function hasIn(object2, path5) {
|
|
9185
|
+
return object2 != null && hasPath(object2, path5, baseHasIn);
|
|
9120
9186
|
}
|
|
9121
9187
|
function keys(object2) {
|
|
9122
9188
|
return isArrayLike(object2) ? arrayLikeKeys(object2) : baseKeys(object2);
|
|
@@ -9124,8 +9190,8 @@ function requireLodash_sortby() {
|
|
|
9124
9190
|
function identity(value) {
|
|
9125
9191
|
return value;
|
|
9126
9192
|
}
|
|
9127
|
-
function property(
|
|
9128
|
-
return isKey(
|
|
9193
|
+
function property(path5) {
|
|
9194
|
+
return isKey(path5) ? baseProperty(toKey(path5)) : basePropertyDeep(path5);
|
|
9129
9195
|
}
|
|
9130
9196
|
module.exports = sortBy;
|
|
9131
9197
|
})(lodash_sortby, lodash_sortby.exports);
|
|
@@ -9556,16 +9622,16 @@ async function reportIfFoundPrivateKeyP12Format({ source, context, t }) {
|
|
|
9556
9622
|
return;
|
|
9557
9623
|
}
|
|
9558
9624
|
try {
|
|
9559
|
-
const
|
|
9560
|
-
const
|
|
9561
|
-
const pfxBytes = new Uint8Array(
|
|
9625
|
+
const fs3 = await import("node:fs");
|
|
9626
|
+
const path5 = await import("node:path");
|
|
9627
|
+
const pfxBytes = new Uint8Array(fs3.readFileSync(source.filePath));
|
|
9562
9628
|
const isGcpServiceAccountP12 = await verifyPkcs12Mac(pfxBytes, GCP_SERVICE_ACCOUNT_P12_PASSWORD);
|
|
9563
9629
|
if (!isGcpServiceAccountP12) {
|
|
9564
9630
|
return;
|
|
9565
9631
|
}
|
|
9566
9632
|
context.report({
|
|
9567
9633
|
message: t("PrivateKeyP12", {
|
|
9568
|
-
FILE_NAME:
|
|
9634
|
+
FILE_NAME: path5.basename(source.filePath)
|
|
9569
9635
|
}),
|
|
9570
9636
|
range: [0, source.content.length]
|
|
9571
9637
|
});
|
|
@@ -11521,6 +11587,87 @@ var hookFileSchema = object({
|
|
|
11521
11587
|
hooks: record(string2(), array(hookEntrySchema)).optional()
|
|
11522
11588
|
}).loose();
|
|
11523
11589
|
|
|
11590
|
+
// src/git-repository.ts
|
|
11591
|
+
import fs from "node:fs";
|
|
11592
|
+
import path3 from "node:path";
|
|
11593
|
+
var repositoryUrls = /* @__PURE__ */ new Map();
|
|
11594
|
+
function missing(error2) {
|
|
11595
|
+
const code = error2.code;
|
|
11596
|
+
return code === "ENOENT" || code === "ENOTDIR";
|
|
11597
|
+
}
|
|
11598
|
+
function readText(file) {
|
|
11599
|
+
try {
|
|
11600
|
+
return fs.readFileSync(file, "utf8");
|
|
11601
|
+
} catch (error2) {
|
|
11602
|
+
if (missing(error2)) return null;
|
|
11603
|
+
throw error2;
|
|
11604
|
+
}
|
|
11605
|
+
}
|
|
11606
|
+
function gitFiles(cwd) {
|
|
11607
|
+
try {
|
|
11608
|
+
if (!fs.statSync(cwd).isDirectory()) return null;
|
|
11609
|
+
} catch (error2) {
|
|
11610
|
+
if (missing(error2)) return null;
|
|
11611
|
+
throw error2;
|
|
11612
|
+
}
|
|
11613
|
+
for (let directory = cwd; ; directory = path3.dirname(directory)) {
|
|
11614
|
+
const dotGit = path3.join(directory, ".git");
|
|
11615
|
+
let stats;
|
|
11616
|
+
try {
|
|
11617
|
+
stats = fs.statSync(dotGit);
|
|
11618
|
+
} catch (error2) {
|
|
11619
|
+
if (!missing(error2)) throw error2;
|
|
11620
|
+
if (path3.dirname(directory) === directory) return null;
|
|
11621
|
+
continue;
|
|
11622
|
+
}
|
|
11623
|
+
if (stats.isDirectory())
|
|
11624
|
+
return { directory: dotGit, config: path3.join(dotGit, "config") };
|
|
11625
|
+
const pointer = /^gitdir:\s*(.+?)\s*$/m.exec(readText(dotGit) ?? "");
|
|
11626
|
+
if (pointer === null) return null;
|
|
11627
|
+
const gitDirectory = path3.resolve(directory, pointer[1]);
|
|
11628
|
+
const common = readText(path3.join(gitDirectory, "commondir"))?.trim();
|
|
11629
|
+
return {
|
|
11630
|
+
directory: gitDirectory,
|
|
11631
|
+
config: path3.join(
|
|
11632
|
+
common ? path3.resolve(gitDirectory, common) : gitDirectory,
|
|
11633
|
+
"config"
|
|
11634
|
+
)
|
|
11635
|
+
};
|
|
11636
|
+
}
|
|
11637
|
+
}
|
|
11638
|
+
function originUrl(config2) {
|
|
11639
|
+
let inOrigin = false;
|
|
11640
|
+
for (const line of config2.split(/\r?\n/)) {
|
|
11641
|
+
const section = /^\s*\[\s*([^\]]+?)\s*\]/.exec(line);
|
|
11642
|
+
if (section !== null) {
|
|
11643
|
+
inOrigin = /^remote\s+"origin"$/i.test(section[1]);
|
|
11644
|
+
continue;
|
|
11645
|
+
}
|
|
11646
|
+
const url = inOrigin ? /^\s*url\s*=\s*(.+?)\s*$/i.exec(line) : null;
|
|
11647
|
+
if (url !== null) return url[1].replace(/^"(.*)"$/, "$1");
|
|
11648
|
+
}
|
|
11649
|
+
return null;
|
|
11650
|
+
}
|
|
11651
|
+
function withoutCredentials(url) {
|
|
11652
|
+
return url.replace(/^([a-z][a-z0-9+.-]*:\/\/)[^/@]*@/i, "$1");
|
|
11653
|
+
}
|
|
11654
|
+
function gitRepositoryUrl(cwd) {
|
|
11655
|
+
const known = repositoryUrls.get(cwd);
|
|
11656
|
+
if (known !== void 0) return known;
|
|
11657
|
+
const files = gitFiles(cwd);
|
|
11658
|
+
const config2 = files === null ? null : readText(files.config);
|
|
11659
|
+
const origin = config2 === null ? null : originUrl(config2);
|
|
11660
|
+
const url = origin === null ? null : withoutCredentials(origin);
|
|
11661
|
+
if (url !== null) repositoryUrls.set(cwd, url);
|
|
11662
|
+
return url;
|
|
11663
|
+
}
|
|
11664
|
+
function gitBranch(cwd) {
|
|
11665
|
+
const files = gitFiles(cwd);
|
|
11666
|
+
const head = files === null ? null : readText(path3.join(files.directory, "HEAD"));
|
|
11667
|
+
const branch = /^ref: refs\/heads\/(.+)\s*$/.exec(head ?? "")?.[1];
|
|
11668
|
+
return branch ?? null;
|
|
11669
|
+
}
|
|
11670
|
+
|
|
11524
11671
|
// src/cursor-hook-entry.ts
|
|
11525
11672
|
var MAX_INPUT_BYTES = 16 * 1024 * 1024;
|
|
11526
11673
|
var MAX_QUEUE_BYTES = 256 * 1024 * 1024;
|
|
@@ -11531,11 +11678,12 @@ var hookInputSchema = object({
|
|
|
11531
11678
|
conversation_id: string2().optional(),
|
|
11532
11679
|
parent_conversation_id: string2().optional(),
|
|
11533
11680
|
subagent_id: string2().optional(),
|
|
11681
|
+
workspace_roots: array(string2()).optional(),
|
|
11534
11682
|
transcript_path: string2().nullable().optional(),
|
|
11535
11683
|
agent_transcript_path: string2().nullable().optional()
|
|
11536
11684
|
}).loose();
|
|
11537
11685
|
async function assertQueueCapacity(directory, incomingBytes) {
|
|
11538
|
-
const names = (await
|
|
11686
|
+
const names = (await fs2.readdir(directory)).filter(
|
|
11539
11687
|
(name) => name.endsWith(".jsonl") || name.endsWith(".tmp")
|
|
11540
11688
|
);
|
|
11541
11689
|
if (names.length >= MAX_QUEUE_FILES)
|
|
@@ -11545,7 +11693,7 @@ async function assertQueueCapacity(directory, incomingBytes) {
|
|
|
11545
11693
|
const sizes = await Promise.all(
|
|
11546
11694
|
names.slice(start, start + 64).map(async (name) => {
|
|
11547
11695
|
try {
|
|
11548
|
-
return (await
|
|
11696
|
+
return (await fs2.stat(path4.join(directory, name))).size;
|
|
11549
11697
|
} catch (error2) {
|
|
11550
11698
|
if (error2 instanceof Error && "code" in error2 && error2.code === "ENOENT")
|
|
11551
11699
|
return 0;
|
|
@@ -11565,28 +11713,28 @@ async function writeRecord(directory, value) {
|
|
|
11565
11713
|
throw new Error("Cursor hook record exceeds the capture limit.");
|
|
11566
11714
|
await assertQueueCapacity(directory, recordBytes);
|
|
11567
11715
|
const id = randomUUID();
|
|
11568
|
-
const temporary =
|
|
11569
|
-
const filename =
|
|
11570
|
-
const handle = await
|
|
11716
|
+
const temporary = path4.join(directory, `${id}.tmp`);
|
|
11717
|
+
const filename = path4.join(directory, `${id}.jsonl`);
|
|
11718
|
+
const handle = await fs2.open(temporary, "wx", 384);
|
|
11571
11719
|
try {
|
|
11572
11720
|
await handle.writeFile(serialized, "utf8");
|
|
11573
11721
|
await handle.sync();
|
|
11574
11722
|
} catch (error2) {
|
|
11575
|
-
await
|
|
11723
|
+
await fs2.rm(temporary, { force: true });
|
|
11576
11724
|
throw error2;
|
|
11577
11725
|
} finally {
|
|
11578
11726
|
await handle.close();
|
|
11579
11727
|
}
|
|
11580
|
-
await
|
|
11728
|
+
await fs2.rename(temporary, filename);
|
|
11581
11729
|
}
|
|
11582
11730
|
async function captureSubagentTranscript(directory, input, capturedAt, transcriptBytes) {
|
|
11583
11731
|
const filename = input.agent_transcript_path;
|
|
11584
|
-
if (filename === null || filename === void 0 || !
|
|
11732
|
+
if (filename === null || filename === void 0 || !path4.isAbsolute(filename))
|
|
11585
11733
|
return;
|
|
11586
|
-
const stats = await
|
|
11734
|
+
const stats = await fs2.stat(filename);
|
|
11587
11735
|
if (!stats.isFile() || stats.size > MAX_SUBAGENT_BYTES)
|
|
11588
11736
|
throw new Error("Cursor subagent transcript exceeds the capture limit.");
|
|
11589
|
-
const contents = await
|
|
11737
|
+
const contents = await fs2.readFile(filename);
|
|
11590
11738
|
const parts = Math.max(1, Math.ceil(contents.length / SUBAGENT_CHUNK_BYTES));
|
|
11591
11739
|
const decoder = new StringDecoder("utf8");
|
|
11592
11740
|
for (let index = 0; index < parts; index += 1) {
|
|
@@ -11635,16 +11783,24 @@ async function main() {
|
|
|
11635
11783
|
let transcriptBytes = null;
|
|
11636
11784
|
if (transcriptPath !== null) {
|
|
11637
11785
|
try {
|
|
11638
|
-
transcriptBytes = (await
|
|
11786
|
+
transcriptBytes = (await fs2.stat(transcriptPath)).size;
|
|
11639
11787
|
} catch (error2) {
|
|
11640
11788
|
if (!(error2 instanceof Error && "code" in error2 && error2.code === "ENOENT"))
|
|
11641
11789
|
throw error2;
|
|
11642
11790
|
}
|
|
11643
11791
|
}
|
|
11644
11792
|
const directory = cursorHookDirectory(dataDirectory);
|
|
11645
|
-
await
|
|
11793
|
+
await fs2.mkdir(directory, { recursive: true, mode: 448 });
|
|
11646
11794
|
const capturedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
11647
|
-
|
|
11795
|
+
const cwd = input.workspace_roots?.[0] ?? null;
|
|
11796
|
+
const git = (hook === "sessionStart" || hook === "beforeSubmitPrompt") && cwd !== null ? { branch: gitBranch(cwd), repository_url: gitRepositoryUrl(cwd) } : null;
|
|
11797
|
+
await writeRecord(directory, {
|
|
11798
|
+
hook,
|
|
11799
|
+
capturedAt,
|
|
11800
|
+
transcriptBytes,
|
|
11801
|
+
input,
|
|
11802
|
+
git
|
|
11803
|
+
});
|
|
11648
11804
|
if (hook === "subagentStop")
|
|
11649
11805
|
await captureSubagentTranscript(
|
|
11650
11806
|
directory,
|
|
@@ -11661,15 +11817,15 @@ main().catch(async (error2) => {
|
|
|
11661
11817
|
const dataDirectory = process.argv[3];
|
|
11662
11818
|
if (dataDirectory) {
|
|
11663
11819
|
try {
|
|
11664
|
-
await
|
|
11820
|
+
await fs2.mkdir(dataDirectory, { recursive: true, mode: 448 });
|
|
11665
11821
|
const temporary = `${cursorHookFailurePath(dataDirectory)}.${randomUUID()}.tmp`;
|
|
11666
|
-
await
|
|
11822
|
+
await fs2.writeFile(
|
|
11667
11823
|
temporary,
|
|
11668
11824
|
`${JSON.stringify({ atMs: Date.now() })}
|
|
11669
11825
|
`,
|
|
11670
11826
|
{ mode: 384 }
|
|
11671
11827
|
);
|
|
11672
|
-
await
|
|
11828
|
+
await fs2.rename(temporary, cursorHookFailurePath(dataDirectory));
|
|
11673
11829
|
} catch (statusError) {
|
|
11674
11830
|
process.stderr.write(
|
|
11675
11831
|
`Iteration could not save the Cursor capture failure: ${statusError instanceof Error ? statusError.message : "unknown error"}
|
package/dist/launcher.js
CHANGED
|
@@ -5779,6 +5779,9 @@ var ZodUUID = /* @__PURE__ */ $constructor("ZodUUID", (inst, def) => {
|
|
|
5779
5779
|
$ZodUUID.init(inst, def);
|
|
5780
5780
|
ZodStringFormat.init(inst, def);
|
|
5781
5781
|
});
|
|
5782
|
+
function uuid2(params) {
|
|
5783
|
+
return _uuid(ZodUUID, params);
|
|
5784
|
+
}
|
|
5782
5785
|
var ZodURL = /* @__PURE__ */ $constructor("ZodURL", (inst, def) => {
|
|
5783
5786
|
$ZodURL.init(inst, def);
|
|
5784
5787
|
ZodStringFormat.init(inst, def);
|
|
@@ -6361,6 +6364,31 @@ function superRefine(fn, params) {
|
|
|
6361
6364
|
return _superRefine(fn, params);
|
|
6362
6365
|
}
|
|
6363
6366
|
|
|
6367
|
+
// ../../node_modules/.pnpm/zod@4.6.4/node_modules/zod/v4/classic/iso.js
|
|
6368
|
+
var iso_exports = {};
|
|
6369
|
+
__export(iso_exports, {
|
|
6370
|
+
ZodISODate: () => ZodISODate,
|
|
6371
|
+
ZodISODateTime: () => ZodISODateTime,
|
|
6372
|
+
ZodISODuration: () => ZodISODuration,
|
|
6373
|
+
ZodISOTime: () => ZodISOTime,
|
|
6374
|
+
date: () => date2,
|
|
6375
|
+
datetime: () => datetime2,
|
|
6376
|
+
duration: () => duration2,
|
|
6377
|
+
time: () => time2
|
|
6378
|
+
});
|
|
6379
|
+
function datetime2(params) {
|
|
6380
|
+
return _isoDateTime(ZodISODateTime, params);
|
|
6381
|
+
}
|
|
6382
|
+
function date2(params) {
|
|
6383
|
+
return _isoDate(ZodISODate, params);
|
|
6384
|
+
}
|
|
6385
|
+
function time2(params) {
|
|
6386
|
+
return _isoTime(ZodISOTime, params);
|
|
6387
|
+
}
|
|
6388
|
+
function duration2(params) {
|
|
6389
|
+
return _isoDuration(ZodISODuration, params);
|
|
6390
|
+
}
|
|
6391
|
+
|
|
6364
6392
|
// ../trace-contracts/dist/index.js
|
|
6365
6393
|
var TRACE_EVENT_TYPES = [
|
|
6366
6394
|
"user_message",
|
|
@@ -6394,6 +6422,47 @@ var TRACE_EVENT_TYPES = [
|
|
|
6394
6422
|
];
|
|
6395
6423
|
var COLLECTOR_SOURCES = ["codex", "claude", "cursor"];
|
|
6396
6424
|
var MAX_TRACE_EVENTS_PER_BATCH = 100;
|
|
6425
|
+
var cursorBillingRequestSchema = object({
|
|
6426
|
+
conversationId: uuid2(),
|
|
6427
|
+
reconcileFromMs: number2().int().nonnegative().nullable(),
|
|
6428
|
+
events: array(object({
|
|
6429
|
+
timestamp: number2().int().nonnegative(),
|
|
6430
|
+
kind: _enum([
|
|
6431
|
+
"included",
|
|
6432
|
+
"paid",
|
|
6433
|
+
"byok",
|
|
6434
|
+
"not_charged",
|
|
6435
|
+
"unknown"
|
|
6436
|
+
]),
|
|
6437
|
+
inputTokens: number2().int().nonnegative().nullable(),
|
|
6438
|
+
outputTokens: number2().int().nonnegative().nullable(),
|
|
6439
|
+
cacheReadTokens: number2().int().nonnegative().nullable(),
|
|
6440
|
+
cacheWriteTokens: number2().int().nonnegative().nullable(),
|
|
6441
|
+
paidUsd: number2().finite().nonnegative().nullable()
|
|
6442
|
+
}).strict()).max(5e3)
|
|
6443
|
+
}).strict();
|
|
6444
|
+
var codexBillingRequestSchema = object({
|
|
6445
|
+
accountFingerprint: string2().regex(/^[0-9a-f]{64}$/),
|
|
6446
|
+
reconcile: boolean2(),
|
|
6447
|
+
tasks: array(object({
|
|
6448
|
+
threadId: uuid2(),
|
|
6449
|
+
createdAt: iso_exports.datetime().nullable(),
|
|
6450
|
+
descendantThreadIds: array(uuid2()).max(900),
|
|
6451
|
+
dataStatus: _enum([
|
|
6452
|
+
"available",
|
|
6453
|
+
"partial",
|
|
6454
|
+
"unavailable",
|
|
6455
|
+
"not_queried"
|
|
6456
|
+
]),
|
|
6457
|
+
usageSource: string2().max(100),
|
|
6458
|
+
balanceUsageCredits: string2().regex(/^[+-]?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d{1,3})?$/).max(128).nullable()
|
|
6459
|
+
}).strict()).max(100),
|
|
6460
|
+
authTurns: array(object({
|
|
6461
|
+
threadId: uuid2(),
|
|
6462
|
+
turnId: uuid2(),
|
|
6463
|
+
mode: _enum(["chatgpt", "api_key", "conflicting"])
|
|
6464
|
+
}).strict()).max(5e3)
|
|
6465
|
+
}).strict();
|
|
6397
6466
|
var UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
6398
6467
|
var TIMESTAMP_PATTERN = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2})$/;
|
|
6399
6468
|
var unpairedSurrogate = /[\uD800-\uDFFF]/u;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "iteration-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"@secretlint/secretlint-rule-preset-recommend": "13.0.6",
|
|
23
23
|
"esbuild": "0.28.2",
|
|
24
24
|
"zod": "4.6.4",
|
|
25
|
-
"iteration-trace-contracts": "0.
|
|
25
|
+
"iteration-trace-contracts": "0.9.0"
|
|
26
26
|
},
|
|
27
27
|
"scripts": {
|
|
28
28
|
"build": "pnpm --filter iteration-trace-contracts build && tsc -p tsconfig.json --noEmit && node build.mjs"
|