mobbdev 1.4.27 → 1.4.28
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.
|
@@ -221,13 +221,18 @@ type RepoState = {
|
|
|
221
221
|
* `GitService.getCurrentRepoState()` so detached-HEAD handling and SHA
|
|
222
222
|
* normalization stay in lockstep across the two clients.
|
|
223
223
|
*
|
|
224
|
-
*
|
|
225
|
-
*
|
|
224
|
+
* The repository URL is the canonical form (parseScmURL().canonicalUrl) for any
|
|
225
|
+
* SCM host, including self-hosted / enterprise remotes (scmType "Unknown"); only
|
|
226
|
+
* an absent or genuinely unparseable remote resolves to `repositoryUrl: null`.
|
|
227
|
+
*
|
|
228
|
+
* Never throws — a non-existent dir, missing git binary, or absent/unparseable
|
|
229
|
+
* remote resolves to null so the daemon hot path can rely on a value.
|
|
226
230
|
*/
|
|
227
231
|
declare function readRepoState(workingDir?: string): Promise<RepoState>;
|
|
228
232
|
/**
|
|
229
|
-
* Gets the
|
|
230
|
-
*
|
|
233
|
+
* Gets the canonical remote repository URL for the working directory's repo, for
|
|
234
|
+
* any SCM host (GitHub, GitLab, Azure DevOps, Bitbucket, and self-hosted /
|
|
235
|
+
* enterprise). Returns null when there is no remote or it can't be parsed.
|
|
231
236
|
*/
|
|
232
237
|
declare function getRepositoryUrl(workingDir?: string): Promise<string | null>;
|
|
233
238
|
/**
|
|
@@ -7829,6 +7829,19 @@ import Debug8 from "debug";
|
|
|
7829
7829
|
import Debug7 from "debug";
|
|
7830
7830
|
import fetch3, { File, fileFrom, FormData } from "node-fetch";
|
|
7831
7831
|
var debug8 = Debug7("mobbdev:upload-file");
|
|
7832
|
+
var MIN_UPLOAD_TIMEOUT_MS = 1e4;
|
|
7833
|
+
var MAX_UPLOAD_TIMEOUT_MS = 6e4;
|
|
7834
|
+
var SLOW_LINK_BYTES_PER_MS = 512;
|
|
7835
|
+
function computeUploadTimeoutMs(file) {
|
|
7836
|
+
if (typeof file === "string") {
|
|
7837
|
+
return MAX_UPLOAD_TIMEOUT_MS;
|
|
7838
|
+
}
|
|
7839
|
+
const sizeAllowanceMs = Math.ceil(file.byteLength / SLOW_LINK_BYTES_PER_MS);
|
|
7840
|
+
return Math.min(
|
|
7841
|
+
MAX_UPLOAD_TIMEOUT_MS,
|
|
7842
|
+
MIN_UPLOAD_TIMEOUT_MS + sizeAllowanceMs
|
|
7843
|
+
);
|
|
7844
|
+
}
|
|
7832
7845
|
var S3UploadError = class extends Error {
|
|
7833
7846
|
constructor(status, s3Code, s3Message) {
|
|
7834
7847
|
super(`Failed to upload the file: ${status}`);
|
|
@@ -7887,11 +7900,12 @@ async function uploadFile({
|
|
|
7887
7900
|
);
|
|
7888
7901
|
}
|
|
7889
7902
|
const agent = getProxyAgent(url);
|
|
7903
|
+
const effectiveSignal = signal ?? AbortSignal.timeout(computeUploadTimeoutMs(file));
|
|
7890
7904
|
const response = await fetch3(url, {
|
|
7891
7905
|
method: "POST",
|
|
7892
7906
|
body: form,
|
|
7893
7907
|
agent,
|
|
7894
|
-
signal
|
|
7908
|
+
signal: effectiveSignal
|
|
7895
7909
|
});
|
|
7896
7910
|
if (!response.ok) {
|
|
7897
7911
|
let bodyText = "";
|
|
@@ -8468,8 +8482,7 @@ async function readRepoState(workingDir) {
|
|
|
8468
8482
|
const repoStatePromise = gitService.getCurrentRepoState().catch(() => ({ branch: null, commitSha: null }));
|
|
8469
8483
|
const repositoryUrlPromise = gitService.getRemoteUrl().then((url) => {
|
|
8470
8484
|
if (!url) return null;
|
|
8471
|
-
|
|
8472
|
-
return parsed?.scmType && parsed.scmType !== "Unknown" ? url : null;
|
|
8485
|
+
return parseScmURL(url)?.canonicalUrl ?? null;
|
|
8473
8486
|
}).catch(() => null);
|
|
8474
8487
|
const [{ branch, commitSha }, repositoryUrl] = await Promise.all([
|
|
8475
8488
|
repoStatePromise,
|
package/dist/index.mjs
CHANGED
|
@@ -14209,6 +14209,41 @@ init_urlParser2();
|
|
|
14209
14209
|
import Debug8 from "debug";
|
|
14210
14210
|
import fetch3, { File, fileFrom, FormData } from "node-fetch";
|
|
14211
14211
|
var debug9 = Debug8("mobbdev:upload-file");
|
|
14212
|
+
var MIN_UPLOAD_TIMEOUT_MS = 1e4;
|
|
14213
|
+
var MAX_UPLOAD_TIMEOUT_MS = 6e4;
|
|
14214
|
+
var SLOW_LINK_BYTES_PER_MS = 512;
|
|
14215
|
+
function computeUploadTimeoutMs(file) {
|
|
14216
|
+
if (typeof file === "string") {
|
|
14217
|
+
return MAX_UPLOAD_TIMEOUT_MS;
|
|
14218
|
+
}
|
|
14219
|
+
const sizeAllowanceMs = Math.ceil(file.byteLength / SLOW_LINK_BYTES_PER_MS);
|
|
14220
|
+
return Math.min(
|
|
14221
|
+
MAX_UPLOAD_TIMEOUT_MS,
|
|
14222
|
+
MIN_UPLOAD_TIMEOUT_MS + sizeAllowanceMs
|
|
14223
|
+
);
|
|
14224
|
+
}
|
|
14225
|
+
var TRANSIENT_ERROR_CODES = /* @__PURE__ */ new Set([
|
|
14226
|
+
"ECONNRESET",
|
|
14227
|
+
"ETIMEDOUT",
|
|
14228
|
+
"ECONNREFUSED",
|
|
14229
|
+
"EPIPE",
|
|
14230
|
+
"EAI_AGAIN",
|
|
14231
|
+
"ENETUNREACH",
|
|
14232
|
+
"ENOTFOUND"
|
|
14233
|
+
]);
|
|
14234
|
+
function isTransientUploadError(err) {
|
|
14235
|
+
if (err instanceof S3UploadError) {
|
|
14236
|
+
return false;
|
|
14237
|
+
}
|
|
14238
|
+
if (typeof err !== "object" || err === null) {
|
|
14239
|
+
return false;
|
|
14240
|
+
}
|
|
14241
|
+
const e = err;
|
|
14242
|
+
if (e.code !== void 0 && TRANSIENT_ERROR_CODES.has(e.code)) {
|
|
14243
|
+
return true;
|
|
14244
|
+
}
|
|
14245
|
+
return e.type === "system" || e.name === "AbortError" || e.name === "TimeoutError";
|
|
14246
|
+
}
|
|
14212
14247
|
var S3UploadError = class extends Error {
|
|
14213
14248
|
constructor(status, s3Code, s3Message) {
|
|
14214
14249
|
super(`Failed to upload the file: ${status}`);
|
|
@@ -14267,11 +14302,12 @@ async function uploadFile({
|
|
|
14267
14302
|
);
|
|
14268
14303
|
}
|
|
14269
14304
|
const agent = getProxyAgent(url);
|
|
14305
|
+
const effectiveSignal = signal ?? AbortSignal.timeout(computeUploadTimeoutMs(file));
|
|
14270
14306
|
const response = await fetch3(url, {
|
|
14271
14307
|
method: "POST",
|
|
14272
14308
|
body: form,
|
|
14273
14309
|
agent,
|
|
14274
|
-
signal
|
|
14310
|
+
signal: effectiveSignal
|
|
14275
14311
|
});
|
|
14276
14312
|
if (!response.ok) {
|
|
14277
14313
|
let bodyText = "";
|
|
@@ -14653,8 +14689,7 @@ async function readRepoState(workingDir) {
|
|
|
14653
14689
|
const repoStatePromise = gitService.getCurrentRepoState().catch(() => ({ branch: null, commitSha: null }));
|
|
14654
14690
|
const repositoryUrlPromise = gitService.getRemoteUrl().then((url) => {
|
|
14655
14691
|
if (!url) return null;
|
|
14656
|
-
|
|
14657
|
-
return parsed?.scmType && parsed.scmType !== "Unknown" ? url : null;
|
|
14692
|
+
return parseScmURL(url)?.canonicalUrl ?? null;
|
|
14658
14693
|
}).catch(() => null);
|
|
14659
14694
|
const [{ branch, commitSha }, repositoryUrl] = await Promise.all([
|
|
14660
14695
|
repoStatePromise,
|
|
@@ -17865,7 +17900,7 @@ import { spawn } from "child_process";
|
|
|
17865
17900
|
import { readFileSync, writeFileSync as writeFileSync2 } from "fs";
|
|
17866
17901
|
import * as os8 from "os";
|
|
17867
17902
|
import path24 from "path";
|
|
17868
|
-
import { setTimeout as
|
|
17903
|
+
import { setTimeout as sleep4 } from "timers/promises";
|
|
17869
17904
|
import Configstore3 from "configstore";
|
|
17870
17905
|
|
|
17871
17906
|
// src/features/analysis/skill_quarantine/runQuarantineCheck.ts
|
|
@@ -18144,23 +18179,61 @@ var SCAN_PATHS = {
|
|
|
18144
18179
|
// src/features/analysis/context_file_scanner.ts
|
|
18145
18180
|
var MAX_CONTEXT_FILE_SIZE = 20 * 1024 * 1024;
|
|
18146
18181
|
var SESSION_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
18182
|
+
var FAILURE_BACKOFF_BASE_MS = 60 * 1e3;
|
|
18183
|
+
var FAILURE_BACKOFF_MAX_MS = 60 * 60 * 1e3;
|
|
18147
18184
|
var sessionMtimes = /* @__PURE__ */ new Map();
|
|
18148
18185
|
function markContextFilesUploaded(sessionId, files, skills) {
|
|
18149
|
-
|
|
18150
|
-
if (!entry) {
|
|
18151
|
-
entry = { files: /* @__PURE__ */ new Map(), skills: /* @__PURE__ */ new Map(), lastUpdatedAt: Date.now() };
|
|
18152
|
-
sessionMtimes.set(sessionId, entry);
|
|
18153
|
-
}
|
|
18186
|
+
const entry = getOrCreateSessionEntry(sessionId);
|
|
18154
18187
|
for (const f of files) {
|
|
18155
18188
|
entry.files.set(f.path, f.mtimeMs);
|
|
18189
|
+
entry.failures.delete(f.path);
|
|
18156
18190
|
}
|
|
18157
18191
|
if (skills) {
|
|
18158
18192
|
for (const sg of skills) {
|
|
18159
18193
|
entry.skills.set(sg.sessionKey, sg.maxMtimeMs);
|
|
18194
|
+
entry.failures.delete(sg.sessionKey);
|
|
18160
18195
|
}
|
|
18161
18196
|
}
|
|
18162
18197
|
entry.lastUpdatedAt = Date.now();
|
|
18163
18198
|
}
|
|
18199
|
+
function markContextUploadFailed(sessionId, files, skills) {
|
|
18200
|
+
const entry = getOrCreateSessionEntry(sessionId);
|
|
18201
|
+
const now = Date.now();
|
|
18202
|
+
const recordFailure = (key) => {
|
|
18203
|
+
const attempts = (entry.failures.get(key)?.attempts ?? 0) + 1;
|
|
18204
|
+
const delay3 = Math.min(
|
|
18205
|
+
FAILURE_BACKOFF_BASE_MS * 2 ** (attempts - 1),
|
|
18206
|
+
FAILURE_BACKOFF_MAX_MS
|
|
18207
|
+
);
|
|
18208
|
+
entry.failures.set(key, { attempts, nextRetryAt: now + delay3 });
|
|
18209
|
+
};
|
|
18210
|
+
for (const f of files) {
|
|
18211
|
+
recordFailure(f.path);
|
|
18212
|
+
}
|
|
18213
|
+
if (skills) {
|
|
18214
|
+
for (const sg of skills) {
|
|
18215
|
+
recordFailure(sg.sessionKey);
|
|
18216
|
+
}
|
|
18217
|
+
}
|
|
18218
|
+
entry.lastUpdatedAt = now;
|
|
18219
|
+
}
|
|
18220
|
+
function getOrCreateSessionEntry(sessionId) {
|
|
18221
|
+
let entry = sessionMtimes.get(sessionId);
|
|
18222
|
+
if (!entry) {
|
|
18223
|
+
entry = {
|
|
18224
|
+
files: /* @__PURE__ */ new Map(),
|
|
18225
|
+
skills: /* @__PURE__ */ new Map(),
|
|
18226
|
+
failures: /* @__PURE__ */ new Map(),
|
|
18227
|
+
lastUpdatedAt: Date.now()
|
|
18228
|
+
};
|
|
18229
|
+
sessionMtimes.set(sessionId, entry);
|
|
18230
|
+
}
|
|
18231
|
+
return entry;
|
|
18232
|
+
}
|
|
18233
|
+
function isInUploadBackoff(entry, key, now) {
|
|
18234
|
+
const failure = entry.failures.get(key);
|
|
18235
|
+
return failure !== void 0 && failure.nextRetryAt > now;
|
|
18236
|
+
}
|
|
18164
18237
|
var COPILOT_CUSTOM_LOCATION_SETTINGS = [
|
|
18165
18238
|
{
|
|
18166
18239
|
key: "chat.agentSkillsLocations",
|
|
@@ -18520,6 +18593,9 @@ async function scanContextFiles(workspaceRoot, platform2, sessionId) {
|
|
|
18520
18593
|
if (prevMtime !== void 0 && fileStat.mtimeMs <= prevMtime) {
|
|
18521
18594
|
continue;
|
|
18522
18595
|
}
|
|
18596
|
+
if (sessionEntry && isInUploadBackoff(sessionEntry, filePath, now)) {
|
|
18597
|
+
continue;
|
|
18598
|
+
}
|
|
18523
18599
|
allFiles.push(fileEntry);
|
|
18524
18600
|
}
|
|
18525
18601
|
} catch {
|
|
@@ -18535,6 +18611,9 @@ async function scanContextFiles(workspaceRoot, platform2, sessionId) {
|
|
|
18535
18611
|
if (prevMtime !== void 0 && group.maxMtimeMs <= prevMtime) {
|
|
18536
18612
|
continue;
|
|
18537
18613
|
}
|
|
18614
|
+
if (isInUploadBackoff(sessionEntry, group.sessionKey, now)) {
|
|
18615
|
+
continue;
|
|
18616
|
+
}
|
|
18538
18617
|
}
|
|
18539
18618
|
allSkillGroups.push(group);
|
|
18540
18619
|
}
|
|
@@ -19123,6 +19202,7 @@ var lastRunAt = /* @__PURE__ */ new Map();
|
|
|
19123
19202
|
var lastDirsMtimeMs = /* @__PURE__ */ new Map();
|
|
19124
19203
|
var seenSkillMd5s = /* @__PURE__ */ new Set();
|
|
19125
19204
|
var killSwitchLogged = false;
|
|
19205
|
+
var optInDisabledLogged = false;
|
|
19126
19206
|
async function runQuarantineCheckIfNeeded(opts) {
|
|
19127
19207
|
const { sessionId, cwd, gqlClient, log: log2 } = opts;
|
|
19128
19208
|
if (process.env[KILL_SWITCH_ENV] === "1") {
|
|
@@ -19149,14 +19229,14 @@ async function runQuarantineCheckIfNeeded(opts) {
|
|
|
19149
19229
|
return;
|
|
19150
19230
|
}
|
|
19151
19231
|
lastDirsMtimeMs.set(sessionId, dirsMtime);
|
|
19152
|
-
log2.
|
|
19232
|
+
log2.debug(
|
|
19153
19233
|
{ sessionId, metric: Metric.CHECK_TRIGGERED, hasNewSkills },
|
|
19154
19234
|
"skill_quarantine: check start"
|
|
19155
19235
|
);
|
|
19156
19236
|
const t0 = Date.now();
|
|
19157
19237
|
try {
|
|
19158
19238
|
await reconcileAndSweep(log2);
|
|
19159
|
-
log2.
|
|
19239
|
+
log2.debug(
|
|
19160
19240
|
{ sessionId, count: installed.length, metric: Metric.SKILLS_CHECKED },
|
|
19161
19241
|
"skill_quarantine: skills enumerated"
|
|
19162
19242
|
);
|
|
@@ -19176,10 +19256,13 @@ async function runQuarantineCheckIfNeeded(opts) {
|
|
|
19176
19256
|
log2
|
|
19177
19257
|
);
|
|
19178
19258
|
if (!quarantineEnabled) {
|
|
19179
|
-
|
|
19180
|
-
|
|
19181
|
-
|
|
19182
|
-
|
|
19259
|
+
if (!optInDisabledLogged) {
|
|
19260
|
+
log2.info(
|
|
19261
|
+
{ sessionId, metric: Metric.CHECK_DISABLED_ORG },
|
|
19262
|
+
"skill_quarantine: opt-in not enabled for any org of caller; skipping enforcement"
|
|
19263
|
+
);
|
|
19264
|
+
optInDisabledLogged = true;
|
|
19265
|
+
}
|
|
19183
19266
|
return;
|
|
19184
19267
|
}
|
|
19185
19268
|
for (const skill of installed) {
|
|
@@ -19204,7 +19287,7 @@ async function runQuarantineCheckIfNeeded(opts) {
|
|
|
19204
19287
|
}
|
|
19205
19288
|
}
|
|
19206
19289
|
} finally {
|
|
19207
|
-
log2.
|
|
19290
|
+
log2.debug(
|
|
19208
19291
|
{
|
|
19209
19292
|
sessionId,
|
|
19210
19293
|
duration_ms: Date.now() - t0,
|
|
@@ -19316,9 +19399,27 @@ import path21 from "path";
|
|
|
19316
19399
|
import { promisify } from "util";
|
|
19317
19400
|
|
|
19318
19401
|
// src/features/analysis/context_file_uploader.ts
|
|
19402
|
+
import { setTimeout as sleep3 } from "timers/promises";
|
|
19319
19403
|
import pLimit7 from "p-limit";
|
|
19320
19404
|
init_client_generates();
|
|
19321
19405
|
var UPLOAD_CONCURRENCY = 5;
|
|
19406
|
+
var UPLOAD_MAX_ATTEMPTS = 2;
|
|
19407
|
+
var UPLOAD_RETRY_BASE_MS = 250;
|
|
19408
|
+
async function uploadWithRetry(args) {
|
|
19409
|
+
for (let attempt = 1; attempt <= UPLOAD_MAX_ATTEMPTS; attempt++) {
|
|
19410
|
+
try {
|
|
19411
|
+
await uploadFile(args);
|
|
19412
|
+
return;
|
|
19413
|
+
} catch (err) {
|
|
19414
|
+
const isLastAttempt = attempt === UPLOAD_MAX_ATTEMPTS;
|
|
19415
|
+
if (isLastAttempt || !isTransientUploadError(err)) {
|
|
19416
|
+
throw err;
|
|
19417
|
+
}
|
|
19418
|
+
const backoff = UPLOAD_RETRY_BASE_MS * 2 ** (attempt - 1) * (1 + Math.random());
|
|
19419
|
+
await sleep3(backoff);
|
|
19420
|
+
}
|
|
19421
|
+
}
|
|
19422
|
+
}
|
|
19322
19423
|
async function uploadContextRecords(opts) {
|
|
19323
19424
|
const {
|
|
19324
19425
|
processedFiles,
|
|
@@ -19339,6 +19440,8 @@ async function uploadContextRecords(opts) {
|
|
|
19339
19440
|
const records = [];
|
|
19340
19441
|
const uploadedFiles = [];
|
|
19341
19442
|
const uploadedSkillGroups = [];
|
|
19443
|
+
const failedFiles = [];
|
|
19444
|
+
const failedSkillGroups = [];
|
|
19342
19445
|
const limit = pLimit7(UPLOAD_CONCURRENCY);
|
|
19343
19446
|
const extraFields = {
|
|
19344
19447
|
...repositoryUrl !== void 0 && { repositoryUrl },
|
|
@@ -19351,13 +19454,14 @@ async function uploadContextRecords(opts) {
|
|
|
19351
19454
|
(pf) => limit(async () => {
|
|
19352
19455
|
const s3Key = `${keyPrefix}ctx-${pf.md5}.bin`;
|
|
19353
19456
|
try {
|
|
19354
|
-
await
|
|
19457
|
+
await uploadWithRetry({
|
|
19355
19458
|
file: Buffer.from(pf.sanitizedContent, "utf-8"),
|
|
19356
19459
|
url,
|
|
19357
19460
|
uploadKey: s3Key,
|
|
19358
19461
|
uploadFields
|
|
19359
19462
|
});
|
|
19360
19463
|
} catch (err) {
|
|
19464
|
+
failedFiles.push(pf.entry);
|
|
19361
19465
|
onFileError?.(pf.entry.name, err);
|
|
19362
19466
|
return;
|
|
19363
19467
|
}
|
|
@@ -19385,13 +19489,14 @@ async function uploadContextRecords(opts) {
|
|
|
19385
19489
|
(ps) => limit(async () => {
|
|
19386
19490
|
const s3Key = `${keyPrefix}skill-${ps.md5}.zip`;
|
|
19387
19491
|
try {
|
|
19388
|
-
await
|
|
19492
|
+
await uploadWithRetry({
|
|
19389
19493
|
file: ps.zipBuffer,
|
|
19390
19494
|
url,
|
|
19391
19495
|
uploadKey: s3Key,
|
|
19392
19496
|
uploadFields
|
|
19393
19497
|
});
|
|
19394
19498
|
} catch (err) {
|
|
19499
|
+
failedSkillGroups.push(ps.group);
|
|
19395
19500
|
onSkillError?.(ps.group.name, err);
|
|
19396
19501
|
return;
|
|
19397
19502
|
}
|
|
@@ -19417,7 +19522,13 @@ async function uploadContextRecords(opts) {
|
|
|
19417
19522
|
)
|
|
19418
19523
|
];
|
|
19419
19524
|
await Promise.allSettled(tasks);
|
|
19420
|
-
return {
|
|
19525
|
+
return {
|
|
19526
|
+
records,
|
|
19527
|
+
uploadedFiles,
|
|
19528
|
+
uploadedSkillGroups,
|
|
19529
|
+
failedFiles,
|
|
19530
|
+
failedSkillGroups
|
|
19531
|
+
};
|
|
19421
19532
|
}
|
|
19422
19533
|
async function runContextFileUploadPipeline(opts) {
|
|
19423
19534
|
const {
|
|
@@ -19443,7 +19554,13 @@ async function runContextFileUploadPipeline(opts) {
|
|
|
19443
19554
|
return null;
|
|
19444
19555
|
}
|
|
19445
19556
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
19446
|
-
const {
|
|
19557
|
+
const {
|
|
19558
|
+
records,
|
|
19559
|
+
uploadedFiles,
|
|
19560
|
+
uploadedSkillGroups,
|
|
19561
|
+
failedFiles,
|
|
19562
|
+
failedSkillGroups
|
|
19563
|
+
} = await uploadContextRecords({
|
|
19447
19564
|
processedFiles,
|
|
19448
19565
|
processedSkills,
|
|
19449
19566
|
keyPrefix,
|
|
@@ -19459,6 +19576,9 @@ async function runContextFileUploadPipeline(opts) {
|
|
|
19459
19576
|
onFileError,
|
|
19460
19577
|
onSkillError
|
|
19461
19578
|
});
|
|
19579
|
+
if (failedFiles.length > 0 || failedSkillGroups.length > 0) {
|
|
19580
|
+
markContextUploadFailed(sessionId, failedFiles, failedSkillGroups);
|
|
19581
|
+
}
|
|
19462
19582
|
if (records.length === 0) {
|
|
19463
19583
|
return { fileCount: 0, skillCount: 0 };
|
|
19464
19584
|
}
|
|
@@ -19810,7 +19930,7 @@ function createLogger(config2) {
|
|
|
19810
19930
|
|
|
19811
19931
|
// src/features/claude_code/hook_logger.ts
|
|
19812
19932
|
var DD_RUM_TOKEN = true ? "pubf59c0182545bfb4c299175119f1abf9b" : "";
|
|
19813
|
-
var CLI_VERSION = true ? "1.4.
|
|
19933
|
+
var CLI_VERSION = true ? "1.4.28" : "unknown";
|
|
19814
19934
|
var NAMESPACE = "mobbdev-claude-code-hook-logs";
|
|
19815
19935
|
var claudeCodeVersion;
|
|
19816
19936
|
function buildDdTags() {
|
|
@@ -19989,7 +20109,7 @@ async function readNewTranscriptEntries(transcriptPath, sessionId, sessionStore,
|
|
|
19989
20109
|
const stat5 = await fh.stat();
|
|
19990
20110
|
fileSize = stat5.size;
|
|
19991
20111
|
if (cursor.byteOffset >= stat5.size) {
|
|
19992
|
-
hookLog.
|
|
20112
|
+
hookLog.debug({ data: { sessionId } }, "No new data in transcript file");
|
|
19993
20113
|
return {
|
|
19994
20114
|
entries: [],
|
|
19995
20115
|
endByteOffset: fileSize,
|
|
@@ -20226,12 +20346,12 @@ async function processTranscript(input, sessionStore, log2, maxEntries = DAEMON_
|
|
|
20226
20346
|
);
|
|
20227
20347
|
const cursorKey = getCursorKey(resolvedTranscriptPath);
|
|
20228
20348
|
if (rawEntries.length === 0) {
|
|
20229
|
-
log2.
|
|
20349
|
+
log2.debug("No new entries to upload");
|
|
20230
20350
|
return { entriesUploaded: 0, entriesSkipped: 0, errors: 0 };
|
|
20231
20351
|
}
|
|
20232
20352
|
const { filtered: entries, filteredOut } = filterEntries(rawEntries);
|
|
20233
20353
|
if (filteredOut > 0) {
|
|
20234
|
-
log2.
|
|
20354
|
+
log2.debug(
|
|
20235
20355
|
{ data: { filteredOut, remaining: entries.length } },
|
|
20236
20356
|
"Filtered out noise entries"
|
|
20237
20357
|
);
|
|
@@ -20914,7 +21034,7 @@ async function startDaemon() {
|
|
|
20914
21034
|
},
|
|
20915
21035
|
"daemon poll cycle"
|
|
20916
21036
|
);
|
|
20917
|
-
await
|
|
21037
|
+
await sleep4(DAEMON_POLL_INTERVAL_MS);
|
|
20918
21038
|
}
|
|
20919
21039
|
}
|
|
20920
21040
|
async function acquirePidFile() {
|