tesseract-agent 0.9.33 → 0.9.34
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-bundle/cli.js +1097 -464
- package/package.json +1 -1
package/dist-bundle/cli.js
CHANGED
|
@@ -27453,10 +27453,10 @@ var init_client = __esm({
|
|
|
27453
27453
|
* collect the result of an `async: true` submission. */
|
|
27454
27454
|
async archive(searchId, output2 = "json") {
|
|
27455
27455
|
const { apiKey, baseUrl } = await this.creds();
|
|
27456
|
-
const
|
|
27457
|
-
if (!/^[A-Za-z0-9_-]{6,128}$/.test(
|
|
27456
|
+
const safe2 = String(searchId).trim();
|
|
27457
|
+
if (!/^[A-Za-z0-9_-]{6,128}$/.test(safe2))
|
|
27458
27458
|
throw new SerpApiError(`Invalid search id "${searchId}".`, "bad_request");
|
|
27459
|
-
const u = _SerpClient.join(baseUrl ?? DEFAULT_BASE_URL, `searches/${
|
|
27459
|
+
const u = _SerpClient.join(baseUrl ?? DEFAULT_BASE_URL, `searches/${safe2}.${output2 === "md" ? "md" : "json"}`);
|
|
27460
27460
|
u.searchParams.set("api_key", apiKey);
|
|
27461
27461
|
return this.getJson(u.toString(), "archive", {}, { billed: false });
|
|
27462
27462
|
}
|
|
@@ -27465,10 +27465,10 @@ var init_client = __esm({
|
|
|
27465
27465
|
* the body is text, and feeding it to JSON.parse is how the markdown path used to throw. */
|
|
27466
27466
|
async archiveMarkdown(searchId) {
|
|
27467
27467
|
const { apiKey, baseUrl } = await this.creds();
|
|
27468
|
-
const
|
|
27469
|
-
if (!/^[A-Za-z0-9_-]{6,128}$/.test(
|
|
27468
|
+
const safe2 = String(searchId).trim();
|
|
27469
|
+
if (!/^[A-Za-z0-9_-]{6,128}$/.test(safe2))
|
|
27470
27470
|
throw new SerpApiError(`Invalid search id "${searchId}".`, "bad_request");
|
|
27471
|
-
const u = _SerpClient.join(baseUrl ?? DEFAULT_BASE_URL, `searches/${
|
|
27471
|
+
const u = _SerpClient.join(baseUrl ?? DEFAULT_BASE_URL, `searches/${safe2}.md`);
|
|
27472
27472
|
u.searchParams.set("api_key", apiKey);
|
|
27473
27473
|
const { text: text9 } = await this.fetchWithRetry(u.toString(), "archive", {}, false);
|
|
27474
27474
|
return { markdown: text9 };
|
|
@@ -29181,7 +29181,123 @@ var init_plan_splitter = __esm({
|
|
|
29181
29181
|
}
|
|
29182
29182
|
});
|
|
29183
29183
|
|
|
29184
|
+
// ../../packages/agent-core/dist/unattended-log.js
|
|
29185
|
+
var unattended_log_exports = {};
|
|
29186
|
+
__export(unattended_log_exports, {
|
|
29187
|
+
readUnattendedDecisions: () => readUnattendedDecisions,
|
|
29188
|
+
recordUnattendedDecision: () => recordUnattendedDecision,
|
|
29189
|
+
recordVerificationDecision: () => recordVerificationDecision,
|
|
29190
|
+
setUnattendedLogSink: () => setUnattendedLogSink,
|
|
29191
|
+
unattendedLogPath: () => unattendedLogPath
|
|
29192
|
+
});
|
|
29193
|
+
import { appendFileSync, closeSync as closeSync3, existsSync as existsSync7, mkdirSync as mkdirSync9, openSync as openSync3, readFileSync as readFileSync13, readSync as readSync2, renameSync as renameSync6, statSync as statSync5 } from "node:fs";
|
|
29194
|
+
import { dirname as dirname7 } from "node:path";
|
|
29195
|
+
function unattendedLogPath() {
|
|
29196
|
+
return daemonPath("unattended.jsonl");
|
|
29197
|
+
}
|
|
29198
|
+
function rolledPath() {
|
|
29199
|
+
return `${unattendedLogPath()}.1`;
|
|
29200
|
+
}
|
|
29201
|
+
function healPrefix(file2) {
|
|
29202
|
+
if (appended)
|
|
29203
|
+
return "";
|
|
29204
|
+
appended = true;
|
|
29205
|
+
try {
|
|
29206
|
+
const size = statSync5(file2).size;
|
|
29207
|
+
if (size === 0)
|
|
29208
|
+
return "";
|
|
29209
|
+
const fd = openSync3(file2, "r");
|
|
29210
|
+
try {
|
|
29211
|
+
const buf = Buffer.alloc(1);
|
|
29212
|
+
readSync2(fd, buf, 0, 1, size - 1);
|
|
29213
|
+
return buf[0] === 10 ? "" : "\n";
|
|
29214
|
+
} finally {
|
|
29215
|
+
closeSync3(fd);
|
|
29216
|
+
}
|
|
29217
|
+
} catch {
|
|
29218
|
+
return "";
|
|
29219
|
+
}
|
|
29220
|
+
}
|
|
29221
|
+
function setUnattendedLogSink(fn) {
|
|
29222
|
+
sink = fn;
|
|
29223
|
+
warned = false;
|
|
29224
|
+
appended = false;
|
|
29225
|
+
}
|
|
29226
|
+
function rotateIfNeeded(file2) {
|
|
29227
|
+
try {
|
|
29228
|
+
if (!existsSync7(file2) || statSync5(file2).size < MAX_BYTES)
|
|
29229
|
+
return;
|
|
29230
|
+
renameSync6(file2, rolledPath());
|
|
29231
|
+
} catch {
|
|
29232
|
+
}
|
|
29233
|
+
}
|
|
29234
|
+
function recordUnattendedDecision(entry) {
|
|
29235
|
+
if (sink) {
|
|
29236
|
+
try {
|
|
29237
|
+
sink(entry);
|
|
29238
|
+
} catch {
|
|
29239
|
+
}
|
|
29240
|
+
return;
|
|
29241
|
+
}
|
|
29242
|
+
try {
|
|
29243
|
+
const file2 = unattendedLogPath();
|
|
29244
|
+
mkdirSync9(dirname7(file2), { recursive: true });
|
|
29245
|
+
rotateIfNeeded(file2);
|
|
29246
|
+
appendFileSync(file2, `${healPrefix(file2)}${JSON.stringify(entry)}
|
|
29247
|
+
`, { mode: 384 });
|
|
29248
|
+
} catch (err2) {
|
|
29249
|
+
if (warned)
|
|
29250
|
+
return;
|
|
29251
|
+
warned = true;
|
|
29252
|
+
console.error("[unattended] decision log unavailable:", err2 instanceof Error ? err2.message : err2);
|
|
29253
|
+
}
|
|
29254
|
+
}
|
|
29255
|
+
function recordVerificationDecision(entry) {
|
|
29256
|
+
recordUnattendedDecision({ ts: (/* @__PURE__ */ new Date()).toISOString(), source: "verification", ...entry });
|
|
29257
|
+
}
|
|
29258
|
+
function readUnattendedDecisions(limit = 200, opts) {
|
|
29259
|
+
const out = [];
|
|
29260
|
+
for (const file2 of [rolledPath(), unattendedLogPath()]) {
|
|
29261
|
+
let text9;
|
|
29262
|
+
try {
|
|
29263
|
+
if (!existsSync7(file2))
|
|
29264
|
+
continue;
|
|
29265
|
+
text9 = readFileSync13(file2, "utf8");
|
|
29266
|
+
} catch {
|
|
29267
|
+
continue;
|
|
29268
|
+
}
|
|
29269
|
+
for (const line of text9.split("\n")) {
|
|
29270
|
+
if (!line.trim())
|
|
29271
|
+
continue;
|
|
29272
|
+
try {
|
|
29273
|
+
const entry = JSON.parse(line);
|
|
29274
|
+
if (opts?.sessionId && entry.sessionId !== opts.sessionId)
|
|
29275
|
+
continue;
|
|
29276
|
+
if (opts?.source && entry.source !== opts.source)
|
|
29277
|
+
continue;
|
|
29278
|
+
out.push(entry);
|
|
29279
|
+
} catch {
|
|
29280
|
+
}
|
|
29281
|
+
}
|
|
29282
|
+
}
|
|
29283
|
+
return limit > 0 && out.length > limit ? out.slice(-limit) : out;
|
|
29284
|
+
}
|
|
29285
|
+
var MAX_BYTES, appended, warned, sink;
|
|
29286
|
+
var init_unattended_log = __esm({
|
|
29287
|
+
"../../packages/agent-core/dist/unattended-log.js"() {
|
|
29288
|
+
"use strict";
|
|
29289
|
+
init_base_paths();
|
|
29290
|
+
MAX_BYTES = 4 * 1024 * 1024;
|
|
29291
|
+
appended = false;
|
|
29292
|
+
warned = false;
|
|
29293
|
+
sink = null;
|
|
29294
|
+
}
|
|
29295
|
+
});
|
|
29296
|
+
|
|
29184
29297
|
// ../../packages/agent-core/dist/unattended.js
|
|
29298
|
+
function errText(err2) {
|
|
29299
|
+
return err2 instanceof Error ? err2.message : String(err2);
|
|
29300
|
+
}
|
|
29185
29301
|
function unattendedModeFor(o) {
|
|
29186
29302
|
if (o.optedIn === true)
|
|
29187
29303
|
return "auto";
|
|
@@ -29232,18 +29348,48 @@ function unattendedAnswer(mode, prompt, opts) {
|
|
|
29232
29348
|
}
|
|
29233
29349
|
}
|
|
29234
29350
|
}
|
|
29351
|
+
function logSubject(prompt) {
|
|
29352
|
+
switch (prompt.kind) {
|
|
29353
|
+
case "permission":
|
|
29354
|
+
case "question":
|
|
29355
|
+
case "plan":
|
|
29356
|
+
return prompt.tool;
|
|
29357
|
+
case "elicitation":
|
|
29358
|
+
return prompt.serverName;
|
|
29359
|
+
case "dialog":
|
|
29360
|
+
return prompt.dialogKind;
|
|
29361
|
+
default:
|
|
29362
|
+
return void 0;
|
|
29363
|
+
}
|
|
29364
|
+
}
|
|
29235
29365
|
function scheduleUnattendedAnswer(prompt, deps) {
|
|
29236
29366
|
if (deps.mode() === "off")
|
|
29237
29367
|
return;
|
|
29368
|
+
const record2 = (mode, outcome, extra = {}) => {
|
|
29369
|
+
recordUnattendedDecision({
|
|
29370
|
+
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
29371
|
+
source: "prompt",
|
|
29372
|
+
...deps.context?.sessionId ? { sessionId: deps.context.sessionId } : {},
|
|
29373
|
+
...deps.context?.engine ? { engine: deps.context.engine } : {},
|
|
29374
|
+
mode,
|
|
29375
|
+
kind: prompt.kind,
|
|
29376
|
+
...logSubject(prompt) ? { subject: logSubject(prompt) } : {},
|
|
29377
|
+
outcome,
|
|
29378
|
+
...extra
|
|
29379
|
+
});
|
|
29380
|
+
};
|
|
29238
29381
|
const timer2 = setTimeout(() => {
|
|
29239
29382
|
const mode = deps.mode();
|
|
29240
|
-
if (mode === "off")
|
|
29383
|
+
if (mode === "off") {
|
|
29384
|
+
record2("off", "skipped", { reason: "unattended switched off before the answer landed" });
|
|
29241
29385
|
return;
|
|
29386
|
+
}
|
|
29242
29387
|
let spent;
|
|
29243
29388
|
try {
|
|
29244
29389
|
spent = deps.charge();
|
|
29245
29390
|
} catch (err2) {
|
|
29246
29391
|
deps.log?.("unattended budget charge failed:", err2);
|
|
29392
|
+
record2(mode, "failed", { reason: `budget charge failed: ${errText(err2)}` });
|
|
29247
29393
|
return;
|
|
29248
29394
|
}
|
|
29249
29395
|
const cappedOut = spent > UNATTENDED_MAX_DECISIONS;
|
|
@@ -29253,6 +29399,7 @@ function scheduleUnattendedAnswer(prompt, deps) {
|
|
|
29253
29399
|
deps.refund();
|
|
29254
29400
|
} catch {
|
|
29255
29401
|
}
|
|
29402
|
+
record2(mode, "skipped", { reason: "no policy answer for this prompt kind", spent });
|
|
29256
29403
|
return;
|
|
29257
29404
|
}
|
|
29258
29405
|
let applied = false;
|
|
@@ -29260,6 +29407,13 @@ function scheduleUnattendedAnswer(prompt, deps) {
|
|
|
29260
29407
|
applied = deps.apply(answer);
|
|
29261
29408
|
} catch (err2) {
|
|
29262
29409
|
deps.log?.("unattended auto-answer failed:", err2);
|
|
29410
|
+
record2(mode, "failed", {
|
|
29411
|
+
reason: `apply failed: ${errText(err2)}`,
|
|
29412
|
+
behavior: answer.behavior,
|
|
29413
|
+
decision: answer.decision,
|
|
29414
|
+
spent,
|
|
29415
|
+
...cappedOut ? { cappedOut } : {}
|
|
29416
|
+
});
|
|
29263
29417
|
return;
|
|
29264
29418
|
}
|
|
29265
29419
|
if (!applied) {
|
|
@@ -29267,9 +29421,21 @@ function scheduleUnattendedAnswer(prompt, deps) {
|
|
|
29267
29421
|
deps.refund();
|
|
29268
29422
|
} catch {
|
|
29269
29423
|
}
|
|
29424
|
+
record2(mode, "skipped", {
|
|
29425
|
+
reason: "prompt already resolved \u2014 answered by a human, or the turn ended",
|
|
29426
|
+
behavior: answer.behavior,
|
|
29427
|
+
decision: answer.decision,
|
|
29428
|
+
spent
|
|
29429
|
+
});
|
|
29270
29430
|
return;
|
|
29271
29431
|
}
|
|
29272
29432
|
deps.log?.(`unattended (${mode}) answered ${prompt.kind}: ${answer.behavior}${cappedOut ? " (budget spent)" : ""} \u2014 ${answer.decision}`);
|
|
29433
|
+
record2(mode, "answered", {
|
|
29434
|
+
behavior: answer.behavior,
|
|
29435
|
+
decision: answer.decision,
|
|
29436
|
+
spent,
|
|
29437
|
+
...cappedOut ? { cappedOut } : {}
|
|
29438
|
+
});
|
|
29273
29439
|
try {
|
|
29274
29440
|
deps.report(answer, cappedOut);
|
|
29275
29441
|
} catch (err2) {
|
|
@@ -29283,6 +29449,7 @@ var init_unattended = __esm({
|
|
|
29283
29449
|
"../../packages/agent-core/dist/unattended.js"() {
|
|
29284
29450
|
"use strict";
|
|
29285
29451
|
init_dist();
|
|
29452
|
+
init_unattended_log();
|
|
29286
29453
|
UNATTENDED_ANSWER_DELAY_MS = 700;
|
|
29287
29454
|
UNATTENDED_MAX_DECISIONS = 100;
|
|
29288
29455
|
UNATTENDED_DECIDE_NOTE = "This is an unattended run \u2014 nobody is at the keyboard to answer, and no answer is coming. Choose the best option yourself, proceed, and briefly note which decision you made and why.";
|
|
@@ -29304,8 +29471,11 @@ var init_unattended = __esm({
|
|
|
29304
29471
|
var reinforced_verification_exports = {};
|
|
29305
29472
|
__export(reinforced_verification_exports, {
|
|
29306
29473
|
RV_CLEAN_STREAK_TO_STOP: () => RV_CLEAN_STREAK_TO_STOP,
|
|
29474
|
+
RV_HISTORY_MAX: () => RV_HISTORY_MAX,
|
|
29307
29475
|
RV_MAX_CYCLES: () => RV_MAX_CYCLES,
|
|
29308
29476
|
RV_MIN_REVIEWED_PCT: () => RV_MIN_REVIEWED_PCT,
|
|
29477
|
+
RV_PHASE_DIRECTIVE: () => RV_PHASE_DIRECTIVE,
|
|
29478
|
+
RV_PHASE_EVIDENCE_ASKS: () => RV_PHASE_EVIDENCE_ASKS,
|
|
29309
29479
|
VERDICT_JSON_SCHEMA: () => VERDICT_JSON_SCHEMA,
|
|
29310
29480
|
blockingIssues: () => blockingIssues,
|
|
29311
29481
|
completenessGrade: () => completenessGrade,
|
|
@@ -29313,13 +29483,15 @@ __export(reinforced_verification_exports, {
|
|
|
29313
29483
|
fixPrompt: () => fixPrompt,
|
|
29314
29484
|
newRvState: () => newRvState,
|
|
29315
29485
|
parseVerdict: () => parseVerdict,
|
|
29486
|
+
phaseGrade: () => phaseGrade,
|
|
29487
|
+
phaseReviewPrompt: () => phaseReviewPrompt,
|
|
29316
29488
|
reviewGrade: () => reviewGrade,
|
|
29317
29489
|
reviewPrompt: () => reviewPrompt,
|
|
29318
29490
|
rvAdvance: () => rvAdvance,
|
|
29319
29491
|
rvDecision: () => rvDecision
|
|
29320
29492
|
});
|
|
29321
29493
|
function newRvState(task) {
|
|
29322
|
-
return { cycles: 0, phase: "idle", cleanStreak: 0, ...task ? { task } : {} };
|
|
29494
|
+
return { cycles: 0, phase: "idle", cleanStreak: 0, phasesDone: 0, phaseAsks: 0, history: [], ...task ? { task } : {} };
|
|
29323
29495
|
}
|
|
29324
29496
|
function blockingIssues(v) {
|
|
29325
29497
|
return v.issues.filter((i) => i.severity === "critical" || i.severity === "major");
|
|
@@ -29339,20 +29511,43 @@ function rvDecision(verdict, state3) {
|
|
|
29339
29511
|
return { kind: "review", prompt: reviewPrompt(state3, verdict) };
|
|
29340
29512
|
return { kind: "done" };
|
|
29341
29513
|
}
|
|
29342
|
-
if (
|
|
29514
|
+
if (state3.phase === "phase-review") {
|
|
29515
|
+
if (blocking.length > 0)
|
|
29516
|
+
return { kind: "fix", prompt: fixPrompt(verdict, state3) };
|
|
29517
|
+
if (!verdict.exercised && state3.phaseAsks < RV_PHASE_EVIDENCE_ASKS) {
|
|
29518
|
+
return { kind: "phase-review", prompt: phaseReviewPrompt(state3, verdict) };
|
|
29519
|
+
}
|
|
29520
|
+
return verdict.taskComplete ? { kind: "review", prompt: reviewPrompt(state3) } : { kind: "continue", prompt: continuePrompt(verdict, state3) };
|
|
29521
|
+
}
|
|
29522
|
+
if (!verdict.taskComplete) {
|
|
29523
|
+
if (verdict.phaseComplete)
|
|
29524
|
+
return { kind: "phase-review", prompt: phaseReviewPrompt(state3, verdict) };
|
|
29343
29525
|
return { kind: "continue", prompt: continuePrompt(verdict, state3) };
|
|
29526
|
+
}
|
|
29344
29527
|
if (blocking.length > 0)
|
|
29345
29528
|
return { kind: "fix", prompt: fixPrompt(verdict, state3) };
|
|
29346
29529
|
return { kind: "review", prompt: reviewPrompt(state3) };
|
|
29347
29530
|
})();
|
|
29348
|
-
if (action.kind === "done" || action.kind === "review")
|
|
29531
|
+
if (action.kind === "done" || action.kind === "review" || action.kind === "phase-review")
|
|
29349
29532
|
return action;
|
|
29350
29533
|
return state3.cycles >= RV_MAX_CYCLES ? { kind: "capped" } : action;
|
|
29351
29534
|
}
|
|
29352
29535
|
function rvAdvance(state3, action, verdict) {
|
|
29353
29536
|
const clean2 = verdict.taskComplete && blockingIssues(verdict).length === 0;
|
|
29354
29537
|
const cleanStreak = state3.phase === "review" ? clean2 ? state3.cleanStreak + 1 : 0 : clean2 ? state3.cleanStreak : 0;
|
|
29355
|
-
const
|
|
29538
|
+
const gate = state3.phase === "review" ? "review" : state3.phase === "phase-review" ? "phase" : "completeness";
|
|
29539
|
+
const next = {
|
|
29540
|
+
...state3,
|
|
29541
|
+
lastVerdict: verdict,
|
|
29542
|
+
cleanStreak,
|
|
29543
|
+
history: [...state3.history, {
|
|
29544
|
+
gate,
|
|
29545
|
+
phaseName: verdict.phaseName,
|
|
29546
|
+
taskComplete: verdict.taskComplete,
|
|
29547
|
+
exercised: verdict.exercised,
|
|
29548
|
+
summary: verdict.summary.slice(0, 200)
|
|
29549
|
+
}].slice(-RV_HISTORY_MAX)
|
|
29550
|
+
};
|
|
29356
29551
|
switch (action.kind) {
|
|
29357
29552
|
// Sending the agent back to work is what the budget counts — a review pass is the
|
|
29358
29553
|
// loop doing its own job, not the agent being given another attempt.
|
|
@@ -29361,12 +29556,59 @@ function rvAdvance(state3, action, verdict) {
|
|
|
29361
29556
|
return { ...next, cycles: state3.cycles + 1, phase: "idle" };
|
|
29362
29557
|
case "review":
|
|
29363
29558
|
return { ...next, phase: "review" };
|
|
29559
|
+
// No cycle, for the same reason a review costs none: the loop asking for evidence is not
|
|
29560
|
+
// the agent being given another attempt. The budget still binds, because every `continue`
|
|
29561
|
+
// and `fix` between phases charges one.
|
|
29562
|
+
case "phase-review":
|
|
29563
|
+
return {
|
|
29564
|
+
...next,
|
|
29565
|
+
phase: "phase-review",
|
|
29566
|
+
// Counted on ENTRY to a checkpoint only. The evidence re-ask stays inside the same
|
|
29567
|
+
// checkpoint, and phaseGrade is explicitly asked to answer `phaseComplete` there too —
|
|
29568
|
+
// so counting it again scored one phase twice, and did it for the phase that had just
|
|
29569
|
+
// failed to produce any evidence at all.
|
|
29570
|
+
phasesDone: state3.phasesDone + (state3.phase !== "phase-review" && verdict.phaseComplete ? 1 : 0),
|
|
29571
|
+
// Entering a checkpoint resets the counter; re-asking within one increments it.
|
|
29572
|
+
phaseAsks: state3.phase === "phase-review" ? state3.phaseAsks + 1 : 0
|
|
29573
|
+
};
|
|
29364
29574
|
case "done":
|
|
29365
29575
|
return { ...next, phase: "done" };
|
|
29366
29576
|
case "capped":
|
|
29367
29577
|
return { ...next, phase: "capped" };
|
|
29368
29578
|
}
|
|
29369
29579
|
}
|
|
29580
|
+
function phaseReviewPrompt(state3, verdict) {
|
|
29581
|
+
const name = verdict?.phaseName?.trim();
|
|
29582
|
+
const notRun = verdict && verdict.exercised === false;
|
|
29583
|
+
return promptLines([
|
|
29584
|
+
"AUTOMATED PHASE CHECKPOINT \u2014 prove this phase before building on it.",
|
|
29585
|
+
"",
|
|
29586
|
+
state3.task ? `The request you are working on:
|
|
29587
|
+
${state3.task}` : void 0,
|
|
29588
|
+
"",
|
|
29589
|
+
name ? `The phase you just finished: ${name}` : "You have just finished a phase of the work.",
|
|
29590
|
+
"",
|
|
29591
|
+
notRun ? "Your last pass did not RUN anything. Reading the code again is not a checkpoint \u2014 run it." : void 0,
|
|
29592
|
+
notRun ? "" : void 0,
|
|
29593
|
+
"Do these, in this order:",
|
|
29594
|
+
"1. RUN it. Execute the tests that cover this phase, or the command/script/request that",
|
|
29595
|
+
" exercises it. Actually run them \u2014 do not describe what would happen.",
|
|
29596
|
+
"2. Paste the command you ran and its real output. If it failed, that is the finding.",
|
|
29597
|
+
"3. Check that what worked BEFORE this phase still works: run the wider test suite, or",
|
|
29598
|
+
" the parts of it this phase could plausibly have broken, and say which you ran.",
|
|
29599
|
+
"4. Only then read the phase's diff for defects the run would not surface.",
|
|
29600
|
+
"",
|
|
29601
|
+
"If this phase genuinely cannot be exercised on its own, say so and say WHY, in one line.",
|
|
29602
|
+
"Do not substitute a description of the code for evidence that it works.",
|
|
29603
|
+
"",
|
|
29604
|
+
SERIOUSNESS_BAR,
|
|
29605
|
+
"",
|
|
29606
|
+
"Report, briefly:",
|
|
29607
|
+
"- what you ran, and the outcome",
|
|
29608
|
+
'- anything serious you found (or "nothing serious")',
|
|
29609
|
+
"- whether the phase is sound enough to build the next one on top of"
|
|
29610
|
+
]);
|
|
29611
|
+
}
|
|
29370
29612
|
function continuePrompt(verdict, state3) {
|
|
29371
29613
|
const missing = verdict.unfinished.length > 0 ? verdict.unfinished.map((u) => `- ${u}`).join("\n") : "- (the request has not been fully delivered \u2014 re-read it and identify what is missing)";
|
|
29372
29614
|
const defects = blockingIssues(verdict);
|
|
@@ -29459,21 +29701,42 @@ ${verdict.unfinished.map((u) => `- ${u}`).join("\n")}` : void 0,
|
|
|
29459
29701
|
function issueLine(i) {
|
|
29460
29702
|
return `- [${i.severity}/${i.kind}] ${i.summary}${i.where ? ` (${i.where})` : ""} \u2014 ${i.impact}`;
|
|
29461
29703
|
}
|
|
29462
|
-
function
|
|
29463
|
-
const
|
|
29464
|
-
|
|
29465
|
-
|
|
29466
|
-
|
|
29704
|
+
function gradeContext(state3, todos) {
|
|
29705
|
+
const out = [
|
|
29706
|
+
"## What the user asked for",
|
|
29707
|
+
state3.task || "(not captured \u2014 judge from the account below)"
|
|
29708
|
+
];
|
|
29709
|
+
if (state3.plan) {
|
|
29710
|
+
out.push("", "## The plan the agent laid out at the start", state3.plan.slice(0, 4e3));
|
|
29711
|
+
}
|
|
29712
|
+
if (state3.history.length > 0) {
|
|
29713
|
+
out.push("", "## What has already been established, oldest first");
|
|
29714
|
+
for (const h of state3.history) {
|
|
29715
|
+
const bits = [
|
|
29716
|
+
`[${h.gate}]`,
|
|
29717
|
+
h.phaseName ? `phase "${h.phaseName}"` : null,
|
|
29718
|
+
h.taskComplete ? "request complete" : "request outstanding",
|
|
29719
|
+
h.gate === "phase" ? h.exercised ? "RAN it" : "did NOT run it" : null,
|
|
29720
|
+
h.summary || null
|
|
29721
|
+
].filter(Boolean);
|
|
29722
|
+
out.push(`- ${bits.join(" \xB7 ")}`);
|
|
29723
|
+
}
|
|
29724
|
+
out.push("", "Use this to judge PROGRESS. If the same claim keeps recurring with nothing", "new established, say so in `summary` and do not keep the run open on it.");
|
|
29725
|
+
}
|
|
29726
|
+
if (todos && todos.length > 0) {
|
|
29727
|
+
out.push("", "## The agent's own checklist at the end of the turn", ...todos.map((t) => `- [${t.status}] ${t.content}`));
|
|
29728
|
+
}
|
|
29729
|
+
return out.join("\n");
|
|
29730
|
+
}
|
|
29731
|
+
function completenessGrade(state3, finalText, todos) {
|
|
29467
29732
|
return {
|
|
29468
29733
|
system: GRADER_SYSTEM,
|
|
29469
29734
|
schema: VERDICT_JSON_SCHEMA,
|
|
29470
29735
|
prompt: [
|
|
29471
|
-
|
|
29472
|
-
task || "(not captured \u2014 judge completeness from the agent's own account below)",
|
|
29736
|
+
gradeContext(state3, todos),
|
|
29473
29737
|
"",
|
|
29474
29738
|
"## What the agent said when it stopped",
|
|
29475
29739
|
finalText.slice(0, 24e3) || "(the agent produced no closing message)",
|
|
29476
|
-
plan,
|
|
29477
29740
|
"",
|
|
29478
29741
|
"## Your task",
|
|
29479
29742
|
"Decide whether the user's request has actually been delivered. Set `taskComplete`",
|
|
@@ -29482,18 +29745,68 @@ ${todos.map((t) => `- [${t.status}] ${t.content}`).join("\n")}` : "";
|
|
|
29482
29745
|
"expected here unless the account admits to something broken. Fill the percentages from",
|
|
29483
29746
|
'what the account evidences; if it evidences nothing, use 0 and confidence "low".',
|
|
29484
29747
|
"",
|
|
29748
|
+
"## The phase checkpoint",
|
|
29749
|
+
"This run is verified AS IT IS BUILT. Separately from whether the whole request is",
|
|
29750
|
+
"done, decide whether the agent has just finished one testable PHASE of it \u2014 a slice",
|
|
29751
|
+
"that leaves the project working and can be exercised on its own.",
|
|
29752
|
+
"",
|
|
29753
|
+
"Set `phaseComplete` true only when BOTH hold:",
|
|
29754
|
+
'- the account describes a coherent slice as finished (not "started", not "in progress"), and',
|
|
29755
|
+
"- `taskComplete` is false \u2014 the whole request is still outstanding.",
|
|
29756
|
+
"A finished REQUEST is not a phase checkpoint; the ordinary completeness path handles it.",
|
|
29757
|
+
"Name that slice in `phaseName` (a few words, the agent's own framing), and put the",
|
|
29758
|
+
"number of phases it still expects in `phasesRemaining` (null if it has not said).",
|
|
29759
|
+
"",
|
|
29760
|
+
"Set `exercised` true only if the account shows the work was actually RUN \u2014 a command",
|
|
29761
|
+
'and its output, a test that executed, an observed result. "I reviewed it", "this should',
|
|
29762
|
+
'work", or a description of what the code does is NOT exercised. When in doubt, false.',
|
|
29763
|
+
"",
|
|
29764
|
+
"Return ONLY this JSON:",
|
|
29765
|
+
VERDICT_SCHEMA
|
|
29766
|
+
].join("\n")
|
|
29767
|
+
};
|
|
29768
|
+
}
|
|
29769
|
+
function phaseGrade(state3, phaseName, reportText, todos) {
|
|
29770
|
+
return {
|
|
29771
|
+
system: GRADER_SYSTEM,
|
|
29772
|
+
schema: VERDICT_JSON_SCHEMA,
|
|
29773
|
+
prompt: [
|
|
29774
|
+
gradeContext(state3, todos),
|
|
29775
|
+
"",
|
|
29776
|
+
phaseName ? `## The phase being checked
|
|
29777
|
+
${phaseName}` : "## The phase being checked\n(unnamed)",
|
|
29778
|
+
"",
|
|
29779
|
+
"## The agent's checkpoint report",
|
|
29780
|
+
reportText.slice(0, 24e3) || "(the agent produced no report)",
|
|
29781
|
+
"",
|
|
29782
|
+
"## Your task",
|
|
29783
|
+
"This was a CHECKPOINT: the agent was told to prove the phase by running it.",
|
|
29784
|
+
"",
|
|
29785
|
+
"`exercised` is the field that matters. Set it true ONLY if the report shows something",
|
|
29786
|
+
"was actually executed \u2014 a command with its real output, a test run with a result, an",
|
|
29787
|
+
'observed behaviour. A description of the code, a claim that it "should work", or a',
|
|
29788
|
+
"read-through of the diff is NOT exercised, however confident it sounds. A report that",
|
|
29789
|
+
"says the phase cannot be exercised on its own, and says why, is also not exercised \u2014",
|
|
29790
|
+
"but that is an honest answer, so do not manufacture issues over it.",
|
|
29791
|
+
"",
|
|
29792
|
+
"Record in `issues` only what the report shows is genuinely broken \u2014 a failing test, a",
|
|
29793
|
+
"command that errored, a regression it found. Do not invent findings from silence.",
|
|
29794
|
+
"",
|
|
29795
|
+
"Set `taskComplete` for the WHOLE request (usually false at a phase checkpoint), and",
|
|
29796
|
+
"`phaseComplete` true if this phase is now sound enough to build on.",
|
|
29797
|
+
"Fill `manuallyTestedPct` from what was actually run, not from what exists.",
|
|
29798
|
+
"",
|
|
29485
29799
|
"Return ONLY this JSON:",
|
|
29486
29800
|
VERDICT_SCHEMA
|
|
29487
29801
|
].join("\n")
|
|
29488
29802
|
};
|
|
29489
29803
|
}
|
|
29490
|
-
function reviewGrade(
|
|
29804
|
+
function reviewGrade(state3, reviewText, todos) {
|
|
29491
29805
|
return {
|
|
29492
29806
|
system: GRADER_SYSTEM,
|
|
29493
29807
|
schema: VERDICT_JSON_SCHEMA,
|
|
29494
29808
|
prompt: [
|
|
29495
|
-
|
|
29496
|
-
task || "(not captured)",
|
|
29809
|
+
gradeContext(state3, todos),
|
|
29497
29810
|
"",
|
|
29498
29811
|
"## The agent's review of its own work",
|
|
29499
29812
|
reviewText.slice(0, 32e3) || "(the agent produced no review)",
|
|
@@ -29535,6 +29848,15 @@ function parseVerdict(raw) {
|
|
|
29535
29848
|
})).slice(0, 40);
|
|
29536
29849
|
return {
|
|
29537
29850
|
taskComplete: o.taskComplete === true,
|
|
29851
|
+
// All four default to the CONSERVATIVE reading. `phaseComplete: false` means "no
|
|
29852
|
+
// checkpoint yet", which costs nothing; a defaulted `true` would fire a phase review at
|
|
29853
|
+
// every turn end. `exercised: false` means "nothing was run", which sends the phase
|
|
29854
|
+
// review back once — the safe direction, because the opposite lets "tested" quietly
|
|
29855
|
+
// come to mean "read", which is the one thing this gate exists to prevent.
|
|
29856
|
+
phaseComplete: o.phaseComplete === true,
|
|
29857
|
+
phaseName: typeof o.phaseName === "string" ? o.phaseName.trim().slice(0, 120) : "",
|
|
29858
|
+
phasesRemaining: typeof o.phasesRemaining === "number" && Number.isFinite(o.phasesRemaining) ? Math.max(0, Math.min(99, Math.round(o.phasesRemaining))) : null,
|
|
29859
|
+
exercised: o.exercised === true,
|
|
29538
29860
|
confidence: o.confidence === "high" || o.confidence === "medium" ? o.confidence : "low",
|
|
29539
29861
|
unfinished: strList(o.unfinished),
|
|
29540
29862
|
issues,
|
|
@@ -29549,13 +29871,14 @@ function parseVerdict(raw) {
|
|
|
29549
29871
|
summary: typeof o.summary === "string" ? o.summary.trim().slice(0, 2e3) : ""
|
|
29550
29872
|
};
|
|
29551
29873
|
}
|
|
29552
|
-
var RV_MIN_REVIEWED_PCT, RV_CLEAN_STREAK_TO_STOP, SEVERITY_LIST, KIND_LIST, SEVERITIES, KINDS2, SERIOUSNESS_BAR, promptLines, VERDICT_SCHEMA, GRADER_SYSTEM, VERDICT_JSON_SCHEMA, NON_BLOCKING_WORDS, pct, tri, strList;
|
|
29874
|
+
var RV_MIN_REVIEWED_PCT, RV_PHASE_EVIDENCE_ASKS, RV_CLEAN_STREAK_TO_STOP, SEVERITY_LIST, KIND_LIST, SEVERITIES, KINDS2, RV_HISTORY_MAX, SERIOUSNESS_BAR, RV_PHASE_DIRECTIVE, promptLines, VERDICT_SCHEMA, GRADER_SYSTEM, VERDICT_JSON_SCHEMA, NON_BLOCKING_WORDS, pct, tri, strList;
|
|
29553
29875
|
var init_reinforced_verification = __esm({
|
|
29554
29876
|
"../../packages/agent-core/dist/reinforced-verification.js"() {
|
|
29555
29877
|
"use strict";
|
|
29556
29878
|
init_dist();
|
|
29557
29879
|
init_dist();
|
|
29558
29880
|
RV_MIN_REVIEWED_PCT = 90;
|
|
29881
|
+
RV_PHASE_EVIDENCE_ASKS = 1;
|
|
29559
29882
|
RV_CLEAN_STREAK_TO_STOP = 2;
|
|
29560
29883
|
SEVERITY_LIST = ["critical", "major", "minor"];
|
|
29561
29884
|
KIND_LIST = [
|
|
@@ -29570,6 +29893,7 @@ var init_reinforced_verification = __esm({
|
|
|
29570
29893
|
];
|
|
29571
29894
|
SEVERITIES = new Set(SEVERITY_LIST);
|
|
29572
29895
|
KINDS2 = new Set(KIND_LIST);
|
|
29896
|
+
RV_HISTORY_MAX = 12;
|
|
29573
29897
|
SERIOUSNESS_BAR = `Only these count as problems worth reporting:
|
|
29574
29898
|
- It breaks functionality that is supposed to work \u2014 now, or for a realistic input.
|
|
29575
29899
|
- It is a regression: something that worked before this run does not work now.
|
|
@@ -29584,9 +29908,26 @@ var init_reinforced_verification = __esm({
|
|
|
29584
29908
|
Explicitly DO NOT report, and do not spend time on: naming, formatting, comment wording,
|
|
29585
29909
|
documentation gaps, test style, micro-optimisation, hypothetical futures, "could be
|
|
29586
29910
|
cleaner", or anything you would not stop a release for. Reporting those wastes the run.`;
|
|
29911
|
+
RV_PHASE_DIRECTIVE = `This run is verified as you build it. Work in PHASES.
|
|
29912
|
+
|
|
29913
|
+
Before you start, split the request into the smallest sequence of phases where each one:
|
|
29914
|
+
- leaves the project in a WORKING state (it builds, and what worked before still works), and
|
|
29915
|
+
- can be EXERCISED on its own \u2014 a test you can run, a command with observable output, a
|
|
29916
|
+
script, a request against a running service. Not "read the diff and see that it is right".
|
|
29917
|
+
|
|
29918
|
+
Then build one phase at a time. When a phase is done, say so plainly \u2014 name the phase, and
|
|
29919
|
+
say how it can be exercised. Do not start the next phase in the same turn: finishing one is
|
|
29920
|
+
a checkpoint, and the checkpoint is where it gets proven.
|
|
29921
|
+
|
|
29922
|
+
If the request is genuinely a single small change, that is one phase. Do not invent phases to
|
|
29923
|
+
look thorough; a phase that cannot be run on its own is not a phase.`;
|
|
29587
29924
|
promptLines = (lines) => lines.filter((l) => l !== void 0).join("\n");
|
|
29588
29925
|
VERDICT_SCHEMA = `{
|
|
29589
29926
|
"taskComplete": boolean,
|
|
29927
|
+
"phaseComplete": boolean,
|
|
29928
|
+
"phaseName": string,
|
|
29929
|
+
"phasesRemaining": number | null,
|
|
29930
|
+
"exercised": boolean,
|
|
29590
29931
|
"confidence": "low" | "medium" | "high",
|
|
29591
29932
|
"unfinished": string[],
|
|
29592
29933
|
"issues": [{
|
|
@@ -29625,9 +29966,16 @@ Respond with ONLY a JSON object matching the schema. No prose, no markdown fence
|
|
|
29625
29966
|
VERDICT_JSON_SCHEMA = {
|
|
29626
29967
|
type: "object",
|
|
29627
29968
|
additionalProperties: false,
|
|
29628
|
-
required: ["taskComplete", "confidence", "unfinished", "issues", "reviewedPct", "testCoveragePct", "manuallyTestedPct", "buildsClean", "testsPass", "verdict", "summary"],
|
|
29969
|
+
required: ["taskComplete", "phaseComplete", "phaseName", "phasesRemaining", "exercised", "confidence", "unfinished", "issues", "reviewedPct", "testCoveragePct", "manuallyTestedPct", "buildsClean", "testsPass", "verdict", "summary"],
|
|
29629
29970
|
properties: {
|
|
29630
29971
|
taskComplete: { type: "boolean" },
|
|
29972
|
+
// REQUIRED, so the grader has to take a position on the checkpoint every time rather
|
|
29973
|
+
// than omitting it and leaving the loop to guess (an omitted field parses to `false`,
|
|
29974
|
+
// which is silently "no checkpoint" — fine as a failure mode, useless as a default).
|
|
29975
|
+
phaseComplete: { type: "boolean" },
|
|
29976
|
+
phaseName: { type: "string" },
|
|
29977
|
+
phasesRemaining: { type: ["integer", "null"] },
|
|
29978
|
+
exercised: { type: "boolean" },
|
|
29631
29979
|
confidence: { type: "string", enum: ["low", "medium", "high"] },
|
|
29632
29980
|
unfinished: { type: "array", items: { type: "string" } },
|
|
29633
29981
|
issues: {
|
|
@@ -29667,6 +30015,74 @@ Respond with ONLY a JSON object matching the schema. No prose, no markdown fence
|
|
|
29667
30015
|
}
|
|
29668
30016
|
});
|
|
29669
30017
|
|
|
30018
|
+
// ../../packages/agent-core/dist/context-recovery.js
|
|
30019
|
+
async function recoverFromContextOverflow(deps) {
|
|
30020
|
+
const mode = safe(deps.mode, "off");
|
|
30021
|
+
if (mode === "off")
|
|
30022
|
+
return false;
|
|
30023
|
+
const record2 = (action, attempt2, reason) => {
|
|
30024
|
+
recordUnattendedDecision({
|
|
30025
|
+
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
30026
|
+
source: "recovery",
|
|
30027
|
+
...deps.context?.sessionId ? { sessionId: deps.context.sessionId } : {},
|
|
30028
|
+
...deps.context?.engine ? { engine: deps.context.engine } : {},
|
|
30029
|
+
mode,
|
|
30030
|
+
kind: "context-overflow",
|
|
30031
|
+
action,
|
|
30032
|
+
attempt: attempt2,
|
|
30033
|
+
...reason ? { reason } : {}
|
|
30034
|
+
});
|
|
30035
|
+
};
|
|
30036
|
+
if (!safe(deps.canCompact, false)) {
|
|
30037
|
+
record2("gave-up", safe(deps.tries, 0), "this engine cannot be asked to compact");
|
|
30038
|
+
return false;
|
|
30039
|
+
}
|
|
30040
|
+
const attempt = safe(deps.tries, 0) + 1;
|
|
30041
|
+
if (attempt > OVERFLOW_MAX_TRIES) {
|
|
30042
|
+
record2("gave-up", attempt, `compaction did not reclaim enough after ${OVERFLOW_MAX_TRIES} attempts`);
|
|
30043
|
+
deps.log?.(`context overflow: giving up after ${OVERFLOW_MAX_TRIES} compaction attempts`);
|
|
30044
|
+
return false;
|
|
30045
|
+
}
|
|
30046
|
+
try {
|
|
30047
|
+
deps.bump();
|
|
30048
|
+
} catch {
|
|
30049
|
+
}
|
|
30050
|
+
try {
|
|
30051
|
+
await deps.compactAndResume();
|
|
30052
|
+
} catch (err2) {
|
|
30053
|
+
deps.log?.("context overflow: compact-and-resume failed", err2);
|
|
30054
|
+
record2("gave-up", attempt, `compact-and-resume failed: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
30055
|
+
return false;
|
|
30056
|
+
}
|
|
30057
|
+
record2("compact-and-resume", attempt);
|
|
30058
|
+
deps.log?.(`context overflow: compacting and resuming (attempt ${attempt}/${OVERFLOW_MAX_TRIES})`);
|
|
30059
|
+
return true;
|
|
30060
|
+
}
|
|
30061
|
+
function safe(fn, fallback) {
|
|
30062
|
+
try {
|
|
30063
|
+
return fn();
|
|
30064
|
+
} catch {
|
|
30065
|
+
return fallback;
|
|
30066
|
+
}
|
|
30067
|
+
}
|
|
30068
|
+
function autoCompactEnvFor(pct2, supplied) {
|
|
30069
|
+
if (supplied?.CLAUDE_AUTOCOMPACT_PCT_OVERRIDE)
|
|
30070
|
+
return {};
|
|
30071
|
+
if (typeof pct2 !== "number" || !Number.isFinite(pct2) || pct2 <= 0 || pct2 >= 100)
|
|
30072
|
+
return {};
|
|
30073
|
+
return { CLAUDE_AUTOCOMPACT_PCT_OVERRIDE: String(Math.round(pct2)) };
|
|
30074
|
+
}
|
|
30075
|
+
var OVERFLOW_MAX_TRIES, OVERFLOW_COMPACT_MESSAGE, OVERFLOW_RESUME_MESSAGE;
|
|
30076
|
+
var init_context_recovery = __esm({
|
|
30077
|
+
"../../packages/agent-core/dist/context-recovery.js"() {
|
|
30078
|
+
"use strict";
|
|
30079
|
+
init_unattended_log();
|
|
30080
|
+
OVERFLOW_MAX_TRIES = 3;
|
|
30081
|
+
OVERFLOW_COMPACT_MESSAGE = "/compact";
|
|
30082
|
+
OVERFLOW_RESUME_MESSAGE = "Continue.";
|
|
30083
|
+
}
|
|
30084
|
+
});
|
|
30085
|
+
|
|
29670
30086
|
// ../../packages/agent-core/dist/session-edit.js
|
|
29671
30087
|
function deleteTranscriptEntry(entries, uuid3, mode = "single") {
|
|
29672
30088
|
const target = entries.find((e) => e.uuid === uuid3);
|
|
@@ -29833,7 +30249,7 @@ var init_session_edit = __esm({
|
|
|
29833
30249
|
});
|
|
29834
30250
|
|
|
29835
30251
|
// ../../packages/agent-core/dist/session-mirror.js
|
|
29836
|
-
import { appendFileSync, existsSync as
|
|
30252
|
+
import { appendFileSync as appendFileSync2, existsSync as existsSync8, mkdirSync as mkdirSync10, readFileSync as readFileSync14, readdirSync, statSync as statSync6, unlinkSync as unlinkSync2 } from "node:fs";
|
|
29837
30253
|
import { join as join16 } from "node:path";
|
|
29838
30254
|
function sessionsRoot() {
|
|
29839
30255
|
return tessPath("sessions");
|
|
@@ -29861,8 +30277,8 @@ function loadSeen(file2) {
|
|
|
29861
30277
|
if (cached3)
|
|
29862
30278
|
return cached3;
|
|
29863
30279
|
const set2 = /* @__PURE__ */ new Set();
|
|
29864
|
-
if (
|
|
29865
|
-
for (const line of
|
|
30280
|
+
if (existsSync8(file2)) {
|
|
30281
|
+
for (const line of readFileSync14(file2, "utf8").split("\n")) {
|
|
29866
30282
|
if (!line.trim())
|
|
29867
30283
|
continue;
|
|
29868
30284
|
try {
|
|
@@ -29883,7 +30299,7 @@ function createLocalSessionStore(opts = {}) {
|
|
|
29883
30299
|
return;
|
|
29884
30300
|
const file2 = fileFor(key2);
|
|
29885
30301
|
try {
|
|
29886
|
-
|
|
30302
|
+
mkdirSync10(join16(file2, ".."), { recursive: true });
|
|
29887
30303
|
withLock(`session-store-${safeSegment(key2.projectKey)}-${safeSegment(key2.sessionId)}`, () => {
|
|
29888
30304
|
const seen = loadSeen(file2);
|
|
29889
30305
|
const lines = [];
|
|
@@ -29897,7 +30313,7 @@ function createLocalSessionStore(opts = {}) {
|
|
|
29897
30313
|
lines.push(JSON.stringify(e));
|
|
29898
30314
|
}
|
|
29899
30315
|
if (lines.length)
|
|
29900
|
-
|
|
30316
|
+
appendFileSync2(file2, `${lines.join("\n")}
|
|
29901
30317
|
`, { mode: 384 });
|
|
29902
30318
|
}, 5e3);
|
|
29903
30319
|
} catch (err2) {
|
|
@@ -29906,11 +30322,11 @@ function createLocalSessionStore(opts = {}) {
|
|
|
29906
30322
|
},
|
|
29907
30323
|
async load(key2) {
|
|
29908
30324
|
const file2 = fileFor(key2);
|
|
29909
|
-
if (!
|
|
30325
|
+
if (!existsSync8(file2))
|
|
29910
30326
|
return null;
|
|
29911
30327
|
try {
|
|
29912
30328
|
const out = [];
|
|
29913
|
-
for (const line of
|
|
30329
|
+
for (const line of readFileSync14(file2, "utf8").split("\n")) {
|
|
29914
30330
|
if (!line.trim())
|
|
29915
30331
|
continue;
|
|
29916
30332
|
try {
|
|
@@ -29926,7 +30342,7 @@ function createLocalSessionStore(opts = {}) {
|
|
|
29926
30342
|
},
|
|
29927
30343
|
async listSessions(projectKey) {
|
|
29928
30344
|
const dir2 = join16(sessionsRoot(), safeSegment(projectKey));
|
|
29929
|
-
if (!
|
|
30345
|
+
if (!existsSync8(dir2))
|
|
29930
30346
|
return [];
|
|
29931
30347
|
const out = [];
|
|
29932
30348
|
for (const name of readdirSync(dir2)) {
|
|
@@ -29936,7 +30352,7 @@ function createLocalSessionStore(opts = {}) {
|
|
|
29936
30352
|
if (base.includes("__"))
|
|
29937
30353
|
continue;
|
|
29938
30354
|
try {
|
|
29939
|
-
out.push({ sessionId: base, mtime: Math.floor(
|
|
30355
|
+
out.push({ sessionId: base, mtime: Math.floor(statSync6(join16(dir2, name)).mtimeMs) });
|
|
29940
30356
|
} catch {
|
|
29941
30357
|
}
|
|
29942
30358
|
}
|
|
@@ -29944,7 +30360,7 @@ function createLocalSessionStore(opts = {}) {
|
|
|
29944
30360
|
},
|
|
29945
30361
|
async listSubkeys(key2) {
|
|
29946
30362
|
const dir2 = join16(sessionsRoot(), safeSegment(key2.projectKey));
|
|
29947
|
-
if (!
|
|
30363
|
+
if (!existsSync8(dir2))
|
|
29948
30364
|
return [];
|
|
29949
30365
|
const prefix = `${safeSegment(key2.sessionId)}__`;
|
|
29950
30366
|
return readdirSync(dir2).filter((n) => n.startsWith(prefix) && n.endsWith(".jsonl")).map((n) => n.slice(prefix.length, -".jsonl".length));
|
|
@@ -29952,13 +30368,13 @@ function createLocalSessionStore(opts = {}) {
|
|
|
29952
30368
|
async delete(key2) {
|
|
29953
30369
|
const file2 = fileFor(key2);
|
|
29954
30370
|
try {
|
|
29955
|
-
if (
|
|
30371
|
+
if (existsSync8(file2))
|
|
29956
30372
|
unlinkSync2(file2);
|
|
29957
30373
|
seenUuids.delete(file2);
|
|
29958
30374
|
if (!key2.subpath) {
|
|
29959
30375
|
const dir2 = join16(sessionsRoot(), safeSegment(key2.projectKey));
|
|
29960
30376
|
const prefix = `${safeSegment(key2.sessionId)}__`;
|
|
29961
|
-
if (
|
|
30377
|
+
if (existsSync8(dir2)) {
|
|
29962
30378
|
for (const n of readdirSync(dir2)) {
|
|
29963
30379
|
if (n.startsWith(prefix) && n.endsWith(".jsonl")) {
|
|
29964
30380
|
try {
|
|
@@ -30835,8 +31251,8 @@ import { query, createSdkMcpServer, startup } from "@anthropic-ai/claude-agent-s
|
|
|
30835
31251
|
import { writeFile as writeFile4, mkdir as mkdir4, readFile as readFile6 } from "node:fs/promises";
|
|
30836
31252
|
import { randomUUID as randomUUID6 } from "node:crypto";
|
|
30837
31253
|
import { tmpdir as tmpdir3, homedir as homedir4, userInfo } from "node:os";
|
|
30838
|
-
import { join as join18, dirname as
|
|
30839
|
-
import { existsSync as
|
|
31254
|
+
import { join as join18, dirname as dirname8 } from "node:path";
|
|
31255
|
+
import { existsSync as existsSync9, readFileSync as readFileSync15, readdirSync as readdirSync2, openSync as openSync4, readSync as readSync3, closeSync as closeSync4, statSync as statSync7, writeFileSync as writeFileSync10, mkdirSync as mkdirSync11, copyFileSync, renameSync as renameSync7 } from "node:fs";
|
|
30840
31256
|
import { fileURLToPath } from "node:url";
|
|
30841
31257
|
import { createRequire as createRequire2 } from "node:module";
|
|
30842
31258
|
import { createServer as createServer2 } from "node:net";
|
|
@@ -30860,11 +31276,11 @@ function findUserInstalledClaude(binName) {
|
|
|
30860
31276
|
"/usr/bin/" + binName
|
|
30861
31277
|
];
|
|
30862
31278
|
for (const p of abs)
|
|
30863
|
-
if (
|
|
31279
|
+
if (existsSync9(p))
|
|
30864
31280
|
return p;
|
|
30865
31281
|
try {
|
|
30866
31282
|
const out = execFileSync2(process.platform === "win32" ? "where" : "which", [binName], { encoding: "utf8" }).split("\n")[0]?.trim();
|
|
30867
|
-
if (out &&
|
|
31283
|
+
if (out && existsSync9(out))
|
|
30868
31284
|
return out;
|
|
30869
31285
|
} catch {
|
|
30870
31286
|
}
|
|
@@ -30889,8 +31305,8 @@ function resolveClaudeCodeExecutable() {
|
|
|
30889
31305
|
for (const key2 of keys) {
|
|
30890
31306
|
try {
|
|
30891
31307
|
const pkgJson = require2.resolve(`@anthropic-ai/claude-agent-sdk-${key2}/package.json`);
|
|
30892
|
-
const bin = join18(
|
|
30893
|
-
if (
|
|
31308
|
+
const bin = join18(dirname8(pkgJson), binName);
|
|
31309
|
+
if (existsSync9(bin))
|
|
30894
31310
|
return cachedClaudeExe = bin;
|
|
30895
31311
|
} catch {
|
|
30896
31312
|
}
|
|
@@ -30900,7 +31316,7 @@ function resolveClaudeCodeExecutable() {
|
|
|
30900
31316
|
const platKey = process.platform === "darwin" ? "mac" : process.platform === "win32" ? "win" : "linux";
|
|
30901
31317
|
for (const dir2 of [`${platKey}-${process.arch}`, platKey]) {
|
|
30902
31318
|
const bundled = join18(resourcesPath, "claude-cli", dir2, binName);
|
|
30903
|
-
if (
|
|
31319
|
+
if (existsSync9(bundled))
|
|
30904
31320
|
return cachedClaudeExe = bundled;
|
|
30905
31321
|
}
|
|
30906
31322
|
}
|
|
@@ -30927,7 +31343,7 @@ function engineCapsPath() {
|
|
|
30927
31343
|
function claudeBinaryStamp() {
|
|
30928
31344
|
try {
|
|
30929
31345
|
const path6 = resolveClaudeCodeExecutable();
|
|
30930
|
-
const st =
|
|
31346
|
+
const st = statSync7(path6);
|
|
30931
31347
|
return `${path6}:${st.size}:${Math.round(st.mtimeMs)}`;
|
|
30932
31348
|
} catch {
|
|
30933
31349
|
return null;
|
|
@@ -30941,7 +31357,7 @@ function loadEngineCaps() {
|
|
|
30941
31357
|
if (!stamp2)
|
|
30942
31358
|
return;
|
|
30943
31359
|
try {
|
|
30944
|
-
const store = JSON.parse(
|
|
31360
|
+
const store = JSON.parse(readFileSync15(engineCapsPath(), "utf8"));
|
|
30945
31361
|
const entry = store[stamp2];
|
|
30946
31362
|
if (entry && (entry.v ?? 1) !== CAPS_VERSION) {
|
|
30947
31363
|
log(`Engine caps: discarding a v${entry.v ?? 1} entry for this binary \u2014 its flags cannot be read under the current rules; they will be re-learned if they still apply.`);
|
|
@@ -30965,7 +31381,7 @@ function saveEngineCaps() {
|
|
|
30965
31381
|
try {
|
|
30966
31382
|
let store = {};
|
|
30967
31383
|
try {
|
|
30968
|
-
store = JSON.parse(
|
|
31384
|
+
store = JSON.parse(readFileSync15(engineCapsPath(), "utf8"));
|
|
30969
31385
|
} catch {
|
|
30970
31386
|
}
|
|
30971
31387
|
store[stamp2] = {
|
|
@@ -30973,7 +31389,7 @@ function saveEngineCaps() {
|
|
|
30973
31389
|
unsupported: [...unsupportedCliOptions],
|
|
30974
31390
|
rejectedArgs: Object.fromEntries([...rejectedCliArgs].map(([f, v]) => [f, [...v]]))
|
|
30975
31391
|
};
|
|
30976
|
-
|
|
31392
|
+
mkdirSync11(tessPath(), { recursive: true });
|
|
30977
31393
|
writeFileSync10(engineCapsPath(), JSON.stringify(store, null, 2), { mode: 384 });
|
|
30978
31394
|
} catch {
|
|
30979
31395
|
}
|
|
@@ -31106,13 +31522,13 @@ function findSessionCwd(sessionId, configDir) {
|
|
|
31106
31522
|
}
|
|
31107
31523
|
for (const slug2 of slugs) {
|
|
31108
31524
|
const file2 = join18(base, slug2, `${sessionId}.jsonl`);
|
|
31109
|
-
if (!
|
|
31525
|
+
if (!existsSync9(file2))
|
|
31110
31526
|
continue;
|
|
31111
31527
|
try {
|
|
31112
|
-
const fd =
|
|
31528
|
+
const fd = openSync4(file2, "r");
|
|
31113
31529
|
const buf = Buffer.alloc(65536);
|
|
31114
|
-
const n =
|
|
31115
|
-
|
|
31530
|
+
const n = readSync3(fd, buf, 0, buf.length, 0);
|
|
31531
|
+
closeSync4(fd);
|
|
31116
31532
|
for (const line of buf.toString("utf-8", 0, n).split("\n")) {
|
|
31117
31533
|
if (!line.trim())
|
|
31118
31534
|
continue;
|
|
@@ -31138,7 +31554,7 @@ function newestVersionManagerNode() {
|
|
|
31138
31554
|
join18(home, "Library", "pnpm", "node"),
|
|
31139
31555
|
join18(home, ".local", "bin", "node")
|
|
31140
31556
|
])
|
|
31141
|
-
if (
|
|
31557
|
+
if (existsSync9(p))
|
|
31142
31558
|
return p;
|
|
31143
31559
|
const roots = [
|
|
31144
31560
|
{ dir: join18(home, ".nvm", "versions", "node"), bin: (v) => join18(v, "bin", "node") },
|
|
@@ -31156,7 +31572,7 @@ function newestVersionManagerNode() {
|
|
|
31156
31572
|
}
|
|
31157
31573
|
for (const name of names) {
|
|
31158
31574
|
const path6 = bin(join18(dir2, name));
|
|
31159
|
-
if (!
|
|
31575
|
+
if (!existsSync9(path6))
|
|
31160
31576
|
continue;
|
|
31161
31577
|
const parts = name.replace(/^v/, "").split(".").map((n) => Number.parseInt(n, 10) || 0);
|
|
31162
31578
|
const ver = [parts[0] ?? 0, parts[1] ?? 0, parts[2] ?? 0];
|
|
@@ -31171,12 +31587,12 @@ function loginShellNode() {
|
|
|
31171
31587
|
if (process.platform === "win32")
|
|
31172
31588
|
return null;
|
|
31173
31589
|
const shell = process.env.SHELL || "/bin/zsh";
|
|
31174
|
-
if (!
|
|
31590
|
+
if (!existsSync9(shell))
|
|
31175
31591
|
return null;
|
|
31176
31592
|
try {
|
|
31177
31593
|
const out = execFileSync2(shell, ["-lic", `printf '<<NODE:%s>>' "$(command -v node 2>/dev/null)"`], { encoding: "utf8", timeout: 4e3, stdio: ["ignore", "pipe", "ignore"] });
|
|
31178
31594
|
const path6 = out.match(/<<NODE:(.*?)>>/)?.[1]?.trim();
|
|
31179
|
-
return path6 &&
|
|
31595
|
+
return path6 && existsSync9(path6) ? path6 : null;
|
|
31180
31596
|
} catch {
|
|
31181
31597
|
return null;
|
|
31182
31598
|
}
|
|
@@ -31187,12 +31603,12 @@ function resolveNodeExecutable() {
|
|
|
31187
31603
|
if (!process.versions.electron)
|
|
31188
31604
|
return cachedNodeExe2 = process.execPath;
|
|
31189
31605
|
for (const p of [process.env.CCB_NODE_PATH, "/opt/homebrew/bin/node", "/usr/local/bin/node", "/usr/bin/node"]) {
|
|
31190
|
-
if (p &&
|
|
31606
|
+
if (p && existsSync9(p))
|
|
31191
31607
|
return cachedNodeExe2 = p;
|
|
31192
31608
|
}
|
|
31193
31609
|
try {
|
|
31194
31610
|
const found = execSync2(process.platform === "win32" ? "where node" : "command -v node", { encoding: "utf8", timeout: 3e3 }).split(/\r?\n/)[0].trim();
|
|
31195
|
-
if (found &&
|
|
31611
|
+
if (found && existsSync9(found))
|
|
31196
31612
|
return cachedNodeExe2 = found;
|
|
31197
31613
|
} catch {
|
|
31198
31614
|
}
|
|
@@ -31626,11 +32042,11 @@ function buildMobileClause(dir2) {
|
|
|
31626
32042
|
try {
|
|
31627
32043
|
let fw = "";
|
|
31628
32044
|
let runCmd = "";
|
|
31629
|
-
if (
|
|
32045
|
+
if (existsSync9(join18(dir2, "pubspec.yaml"))) {
|
|
31630
32046
|
fw = "Flutter";
|
|
31631
32047
|
runCmd = "flutter run -d chrome";
|
|
31632
|
-
} else if (
|
|
31633
|
-
const pkg = JSON.parse(
|
|
32048
|
+
} else if (existsSync9(join18(dir2, "package.json"))) {
|
|
32049
|
+
const pkg = JSON.parse(readFileSync15(join18(dir2, "package.json"), "utf8"));
|
|
31634
32050
|
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
31635
32051
|
if (deps.expo) {
|
|
31636
32052
|
fw = "Expo";
|
|
@@ -31713,6 +32129,8 @@ var init_agent_manager = __esm({
|
|
|
31713
32129
|
init_plan_splitter();
|
|
31714
32130
|
init_unattended();
|
|
31715
32131
|
init_reinforced_verification();
|
|
32132
|
+
init_unattended_log();
|
|
32133
|
+
init_context_recovery();
|
|
31716
32134
|
init_dist();
|
|
31717
32135
|
init_dist();
|
|
31718
32136
|
init_base_paths();
|
|
@@ -31887,6 +32305,15 @@ var init_agent_manager = __esm({
|
|
|
31887
32305
|
* the host (setVerifierLlm); null ⇒ reinforced verification cannot grade, and says so
|
|
31888
32306
|
* rather than letting a run pass unverified. */
|
|
31889
32307
|
verifierLlm = null;
|
|
32308
|
+
/** The user's auto-compact threshold, read from the DAEMON's settings snapshot.
|
|
32309
|
+
*
|
|
32310
|
+
* Exists because the desktop-only route does not cover an unattended run. The threshold
|
|
32311
|
+
* normally reaches the CLI as `CLAUDE_AUTOCOMPACT_PCT_OVERRIDE` inside `params.env`,
|
|
32312
|
+
* which the desktop main process fills in per send (`getAgentSettings`) — so a turn the
|
|
32313
|
+
* DAEMON originates (a cron fire, or anything sent while the app is closed) carried no
|
|
32314
|
+
* threshold at all and ran at the CLI's own default instead of the number the user set.
|
|
32315
|
+
* The other three engines already read this daemon-side at spawn; this is Claude's. */
|
|
32316
|
+
autoCompactPct = null;
|
|
31890
32317
|
/** Plugin-contributed Pre/PostToolUse hooks (Epic G). Appended (never replacing) the
|
|
31891
32318
|
* built-in edit-capture hooks at session start. */
|
|
31892
32319
|
pluginHooks = [];
|
|
@@ -32158,7 +32585,7 @@ var init_agent_manager = __esm({
|
|
|
32158
32585
|
constructor(rawSend2, onBrowserRequest) {
|
|
32159
32586
|
this.rawSend = rawSend2;
|
|
32160
32587
|
this.onBrowserRequest = onBrowserRequest;
|
|
32161
|
-
const __dirname =
|
|
32588
|
+
const __dirname = dirname8(fileURLToPath(import.meta.url));
|
|
32162
32589
|
this.browserCliPath = join18(__dirname, "browser-cli.js");
|
|
32163
32590
|
this.narrator = new Narrator((sessionId, text9, engineLabel) => this.send({ type: "agent:narration", sessionId, text: text9, ...engineLabel ? { engineLabel } : {} }, this.liveSessions.get(sessionId)?.origin));
|
|
32164
32591
|
}
|
|
@@ -32168,6 +32595,67 @@ var init_agent_manager = __esm({
|
|
|
32168
32595
|
setVerifierLlm(fn) {
|
|
32169
32596
|
this.verifierLlm = fn;
|
|
32170
32597
|
}
|
|
32598
|
+
/**
|
|
32599
|
+
* Compact and resume after this session outgrew the window, when nobody is watching.
|
|
32600
|
+
*
|
|
32601
|
+
* Returns true when the recovery was dispatched, in which case the caller must NOT report
|
|
32602
|
+
* the turn as finished — the run continues on a reclaimed window.
|
|
32603
|
+
*
|
|
32604
|
+
* The two sends mirror the renderer's `continueLastTurn(id, 'context_window')` exactly,
|
|
32605
|
+
* because they have to agree: `/compact` alone just compacts and stops, and the resume
|
|
32606
|
+
* alone overflows again. Both ride `autoContinuation`, which is what tells the rest of
|
|
32607
|
+
* the manager this is the SAME run — without it the verification loop would re-anchor on
|
|
32608
|
+
* the literal request "Continue.", which the very next turn satisfies by construction.
|
|
32609
|
+
*/
|
|
32610
|
+
async recoverContextOverflow(live, turnSid) {
|
|
32611
|
+
return recoverFromContextOverflow({
|
|
32612
|
+
mode: () => live.unattended ?? "off",
|
|
32613
|
+
// Claude takes `/compact` as a real slash command.
|
|
32614
|
+
canCompact: () => true,
|
|
32615
|
+
tries: () => live.overflowTries ?? 0,
|
|
32616
|
+
bump: () => {
|
|
32617
|
+
live.overflowTries = (live.overflowTries ?? 0) + 1;
|
|
32618
|
+
},
|
|
32619
|
+
context: { sessionId: turnSid, engine: "claude-code" },
|
|
32620
|
+
log: (m, err2) => log(m, err2 instanceof Error ? err2.message : err2 !== void 0 ? String(err2) : ""),
|
|
32621
|
+
compactAndResume: async () => {
|
|
32622
|
+
const base = {
|
|
32623
|
+
url: "",
|
|
32624
|
+
sessionId: live.sessionId,
|
|
32625
|
+
projectDir: live.cwd,
|
|
32626
|
+
origin: live.origin,
|
|
32627
|
+
browserId: live.browserId,
|
|
32628
|
+
windowId: live.windowId,
|
|
32629
|
+
autoContinuation: true,
|
|
32630
|
+
...live.unattended === "auto" ? { unattended: true } : {},
|
|
32631
|
+
...live.model ? { model: live.model } : {}
|
|
32632
|
+
};
|
|
32633
|
+
await this.sendMessage({ ...base, message: OVERFLOW_COMPACT_MESSAGE });
|
|
32634
|
+
await this.sendMessage({ ...base, message: OVERFLOW_RESUME_MESSAGE });
|
|
32635
|
+
}
|
|
32636
|
+
});
|
|
32637
|
+
}
|
|
32638
|
+
/** Inject the daemon's view of the auto-compact threshold. Read at SPAWN, never
|
|
32639
|
+
* captured, so flipping the slider at 23:00 reaches a session started at 03:00. */
|
|
32640
|
+
setAutoCompactPct(fn) {
|
|
32641
|
+
this.autoCompactPct = fn;
|
|
32642
|
+
}
|
|
32643
|
+
/**
|
|
32644
|
+
* `CLAUDE_AUTOCOMPACT_PCT_OVERRIDE` for a spawn the desktop did not configure.
|
|
32645
|
+
*
|
|
32646
|
+
* Empty whenever the caller already supplied one (the desktop's per-send env wins), when
|
|
32647
|
+
* no provider is wired, or when the number is not a usable percentage — 0 and 100 both
|
|
32648
|
+
* mean "no proactive compaction", and writing either would turn the CLI's own default
|
|
32649
|
+
* OFF rather than leaving it alone. Never throws: a settings read that fails must not
|
|
32650
|
+
* take the spawn with it.
|
|
32651
|
+
*/
|
|
32652
|
+
daemonCompactEnv(supplied) {
|
|
32653
|
+
try {
|
|
32654
|
+
return autoCompactEnvFor(this.autoCompactPct?.(), supplied);
|
|
32655
|
+
} catch {
|
|
32656
|
+
return {};
|
|
32657
|
+
}
|
|
32658
|
+
}
|
|
32171
32659
|
setNarrationLlm(cfg2) {
|
|
32172
32660
|
this.narrator.setConfig(cfg2);
|
|
32173
32661
|
this.cheapLlm = cfg2?.complete ?? null;
|
|
@@ -32353,7 +32841,7 @@ ${full.slice(-8e3)}`;
|
|
|
32353
32841
|
if (live.rvGrading === rv)
|
|
32354
32842
|
return;
|
|
32355
32843
|
live.rvGrading = rv;
|
|
32356
|
-
const gate = rv.phase === "review" ? "review" : "completeness";
|
|
32844
|
+
const gate = rv.phase === "review" ? "review" : rv.phase === "phase-review" ? "phase" : "completeness";
|
|
32357
32845
|
let owned = rv;
|
|
32358
32846
|
const evtSessionId = live.sessionId;
|
|
32359
32847
|
const evtCrid = live.clientRequestId;
|
|
@@ -32366,7 +32854,7 @@ ${full.slice(-8e3)}`;
|
|
|
32366
32854
|
this.send(evt, evtOrigin);
|
|
32367
32855
|
};
|
|
32368
32856
|
try {
|
|
32369
|
-
if (!didWork && gate
|
|
32857
|
+
if (!didWork && gate === "completeness") {
|
|
32370
32858
|
emitVerification({ action: "done", gate, cycle: rv.cycles, maxCycles: RV_MAX_CYCLES, unavailable: "This turn used no tools, so there was nothing to verify." });
|
|
32371
32859
|
return;
|
|
32372
32860
|
}
|
|
@@ -32377,7 +32865,7 @@ ${full.slice(-8e3)}`;
|
|
|
32377
32865
|
return;
|
|
32378
32866
|
}
|
|
32379
32867
|
const todos = live.todos?.map((t) => ({ content: t.content, status: String(t.status) }));
|
|
32380
|
-
const call3 = gate === "review" ? reviewGrade(rv.
|
|
32868
|
+
const call3 = gate === "review" ? reviewGrade(rv, finalText, todos) : gate === "phase" ? phaseGrade(rv, rv.lastVerdict?.phaseName ?? "", finalText, todos) : completenessGrade(rv, finalText, todos);
|
|
32381
32869
|
const raw = await llm({ model: live.model, system: call3.system, prompt: call3.prompt, maxTokens: 16e3, schema: call3.schema });
|
|
32382
32870
|
if (live.rv !== rv || live.reaped) {
|
|
32383
32871
|
if (live.reaped || live.rv === void 0) {
|
|
@@ -32391,12 +32879,28 @@ ${full.slice(-8e3)}`;
|
|
|
32391
32879
|
live.rv = { ...rv, phase: "done" };
|
|
32392
32880
|
return;
|
|
32393
32881
|
}
|
|
32882
|
+
if (!rv.plan && finalText.trim())
|
|
32883
|
+
rv.plan = finalText.slice(0, 4e3);
|
|
32394
32884
|
const action = rvDecision(verdict, rv);
|
|
32395
32885
|
const nextState = rvAdvance(rv, action, verdict);
|
|
32396
32886
|
live.rv = nextState;
|
|
32397
32887
|
owned = nextState;
|
|
32398
32888
|
emitVerification({ action: action.kind, gate, cycle: nextState.cycles, maxCycles: RV_MAX_CYCLES, verdict });
|
|
32399
32889
|
log(`reinforced-verification: ${gate} \u2192 ${action.kind} (cycle ${nextState.cycles}/${RV_MAX_CYCLES}, ${verdict.issues.length} issue(s), complete=${verdict.taskComplete})`);
|
|
32890
|
+
recordVerificationDecision({
|
|
32891
|
+
sessionId: live.sessionId,
|
|
32892
|
+
engine: "claude-code",
|
|
32893
|
+
gate,
|
|
32894
|
+
action: action.kind,
|
|
32895
|
+
cycle: nextState.cycles,
|
|
32896
|
+
phasesDone: nextState.phasesDone,
|
|
32897
|
+
phaseName: verdict.phaseName,
|
|
32898
|
+
taskComplete: verdict.taskComplete,
|
|
32899
|
+
phaseComplete: verdict.phaseComplete,
|
|
32900
|
+
exercised: verdict.exercised,
|
|
32901
|
+
blocking: blockingIssues(verdict).length,
|
|
32902
|
+
summary: verdict.summary
|
|
32903
|
+
});
|
|
32400
32904
|
if (action.kind === "done" || action.kind === "capped")
|
|
32401
32905
|
return;
|
|
32402
32906
|
await this.sendMessage({
|
|
@@ -32476,6 +32980,7 @@ ${full.slice(-8e3)}`;
|
|
|
32476
32980
|
* Abandoning it is a hang — the precise failure this whole path exists to prevent. */
|
|
32477
32981
|
autoAnswerPrompt(live, requestId, prompt, apply2) {
|
|
32478
32982
|
scheduleUnattendedAnswer(prompt, {
|
|
32983
|
+
context: { sessionId: live.sessionId, engine: "claude-code" },
|
|
32479
32984
|
mode: () => live.unattended ?? "off",
|
|
32480
32985
|
charge: () => live.autoDecisions = (live.autoDecisions ?? 0) + 1,
|
|
32481
32986
|
// Relative, not absolute — siblings can be mid-window; see the deps doc.
|
|
@@ -32890,7 +33395,7 @@ ${qText}`;
|
|
|
32890
33395
|
if (!file2)
|
|
32891
33396
|
return { ok: false, reason: "This conversation has no transcript on this machine." };
|
|
32892
33397
|
try {
|
|
32893
|
-
const before = parseTranscript(
|
|
33398
|
+
const before = parseTranscript(readFileSync15(file2, "utf8"));
|
|
32894
33399
|
const want = typeof locator === "string" ? { uuid: locator } : locator;
|
|
32895
33400
|
const uuid3 = want.uuid ?? (want.text ? findUserEntryByText(before, want.text)?.uuid : void 0);
|
|
32896
33401
|
if (!uuid3) {
|
|
@@ -32905,7 +33410,7 @@ ${qText}`;
|
|
|
32905
33410
|
}
|
|
32906
33411
|
const tmp = `${file2}.tmp-${randomUUID6().slice(0, 8)}`;
|
|
32907
33412
|
writeFileSync10(tmp, serializeTranscript(res.entries), { mode: 384 });
|
|
32908
|
-
|
|
33413
|
+
renameSync7(tmp, file2);
|
|
32909
33414
|
log(`Removed ${res.removed.length} transcript entr${res.removed.length === 1 ? "y" : "ies"} from ${sessionId}; re-parented ${res.relinked.length}.`);
|
|
32910
33415
|
if (live) {
|
|
32911
33416
|
try {
|
|
@@ -33300,12 +33805,12 @@ ${qText}`;
|
|
|
33300
33805
|
const cli = `ELECTRON_RUN_AS_NODE=1 "${process.execPath}" "${this.browserCliPath}"`;
|
|
33301
33806
|
const pageInfo = url2 ? `
|
|
33302
33807
|
The user's current browser tab is: ${url2}` : "";
|
|
33303
|
-
const designClause = this.projectDir &&
|
|
33808
|
+
const designClause = this.projectDir && existsSync9(join18(this.projectDir, TOKENS_FILE)) ? `
|
|
33304
33809
|
|
|
33305
33810
|
DESIGN SYSTEM:
|
|
33306
33811
|
- This project has a design system at design-system/tokens.json. For any UI you build or edit, use those tokens (colors, spacing, typography, radius) \u2014 call read_design_tokens to read values, set them with write_design_token, and NEVER hardcode hex/sizes that duplicate a token.` : "";
|
|
33307
33812
|
const mobileClause = this.projectDir ? buildMobileClause(this.projectDir) : "";
|
|
33308
|
-
const buildClause = this.projectDir &&
|
|
33813
|
+
const buildClause = this.projectDir && existsSync9(join18(this.projectDir, ".tesseract", "brief.md")) ? `
|
|
33309
33814
|
|
|
33310
33815
|
WEBSITE BUILD MODE:
|
|
33311
33816
|
This is a guided website build. Read \`.tesseract/brief.md\` (the user's brief), \`design-system/reference.html\` (the chosen template \u2014 the visual/structural spec) and \`design-system/tokens.json\` (the theme). Protocol:
|
|
@@ -33359,8 +33864,8 @@ CRITICAL RULES:
|
|
|
33359
33864
|
const match = f.dataUrl.match(/^data:[^;]*;base64,(.+)$/);
|
|
33360
33865
|
if (!match)
|
|
33361
33866
|
continue;
|
|
33362
|
-
const
|
|
33363
|
-
const filePath = join18(fileDir, `${process.pid}-${Date.now()}-${randomUUID6().slice(0, 8)}-${i}-${
|
|
33867
|
+
const safe2 = (f.name || `file-${i}`).replace(/[^\w.\-]+/g, "_").slice(-100);
|
|
33868
|
+
const filePath = join18(fileDir, `${process.pid}-${Date.now()}-${randomUUID6().slice(0, 8)}-${i}-${safe2}`);
|
|
33364
33869
|
await writeFile4(filePath, Buffer.from(match[1], "base64"));
|
|
33365
33870
|
paths.push(filePath);
|
|
33366
33871
|
}
|
|
@@ -33518,7 +34023,7 @@ CRITICAL RULES:
|
|
|
33518
34023
|
let pinnedSource;
|
|
33519
34024
|
if (params.sessionId) {
|
|
33520
34025
|
const originCwd = findSessionCwd(params.sessionId, params.engineEnv?.CLAUDE_CONFIG_DIR ?? params.env?.CLAUDE_CONFIG_DIR);
|
|
33521
|
-
if (originCwd && originCwd !== openProject &&
|
|
34026
|
+
if (originCwd && originCwd !== openProject && existsSync9(originCwd)) {
|
|
33522
34027
|
log(`Resuming ${params.sessionId} in its ORIGINAL cwd ${originCwd} (open project ${openProject} added as a source)`);
|
|
33523
34028
|
cwd = originCwd;
|
|
33524
34029
|
pinnedSource = openProject;
|
|
@@ -34169,6 +34674,11 @@ CRITICAL RULES:
|
|
|
34169
34674
|
// (getAgentSettings) — IF this CLI honours it, native mid-run compaction fires
|
|
34170
34675
|
// at the same threshold as our renderer-side proactive `/compact`.
|
|
34171
34676
|
...params.env ?? {},
|
|
34677
|
+
// FALLBACK, not an override: `params.env` wins whenever the desktop supplied a
|
|
34678
|
+
// threshold. This fills the gap for a turn the daemon originated itself, which
|
|
34679
|
+
// carries no env — without it an unattended run compacts at the CLI's default
|
|
34680
|
+
// rather than the number in the run-mode menu.
|
|
34681
|
+
...this.daemonCompactEnv(params.env),
|
|
34172
34682
|
...params.engineEnv ?? {},
|
|
34173
34683
|
CCB_IPC_PORT: String(live.ipcPort)
|
|
34174
34684
|
};
|
|
@@ -34208,9 +34718,16 @@ CRITICAL RULES:
|
|
|
34208
34718
|
// restores the SDK's dynamic command list, gitStatus/date context,
|
|
34209
34719
|
// env-info and memory/CLAUDE.md preamble that a bare custom string
|
|
34210
34720
|
// prompt suppresses — while `append` keeps the Tesseract browser tools.
|
|
34721
|
+
// The phase directive rides here when verification is armed. It has to be in the
|
|
34722
|
+
// SYSTEM prompt, not prepended to the user's message: the loop only speaks at turn
|
|
34723
|
+
// END, so without this the agent has already built the whole thing monolithically by
|
|
34724
|
+
// the time anything can ask it to work in slices — and rewriting the user's message
|
|
34725
|
+
// is the mistake that made `/compact` the graded task.
|
|
34211
34726
|
systemPrompt: { type: "preset", preset: "claude_code", append: this.applyPromptHook(this.buildSystemPrompt(params.url) + (params.appendSystemPrompt ? `
|
|
34212
34727
|
|
|
34213
|
-
${params.appendSystemPrompt}` : "")
|
|
34728
|
+
${params.appendSystemPrompt}` : "") + (params.reinforcedVerification ? `
|
|
34729
|
+
|
|
34730
|
+
${RV_PHASE_DIRECTIVE}` : ""), live.sessionId) },
|
|
34214
34731
|
includePartialMessages: true,
|
|
34215
34732
|
// Emit a predicted follow-up prompt after each turn (git/context-aware) — rendered
|
|
34216
34733
|
// as a clickable suggestion chip. Off by default in the SDK, so opt in here.
|
|
@@ -34569,6 +35086,7 @@ ${params.appendSystemPrompt}` : ""), live.sessionId) },
|
|
|
34569
35086
|
if (limitRejection) {
|
|
34570
35087
|
reportUsageLimit(limitRejection, turnSid);
|
|
34571
35088
|
} else if (r.subtype === "success") {
|
|
35089
|
+
live.overflowTries = 0;
|
|
34572
35090
|
if (!turnStreamed && Array.isArray(live.lastAssistantContent)) {
|
|
34573
35091
|
for (const blk of live.lastAssistantContent) {
|
|
34574
35092
|
if (blk?.type === "thinking" && typeof blk.thinking === "string" && blk.thinking) {
|
|
@@ -34618,8 +35136,11 @@ ${params.appendSystemPrompt}` : ""), live.sessionId) },
|
|
|
34618
35136
|
const looksTransient = !contextHit && /overloaded|\b429\b|\b529\b|rate.?limit|too many requests|throttl|\b50[0234]\b|service unavailable|bad gateway|gateway timeout|timed? ?out|ETIMEDOUT|ECONNRESET|ECONNREFUSED|EPIPE|ENOTFOUND|ENETUNREACH|EAI_AGAIN|socket hang up|network error|temporarily unavailable/i.test(detail);
|
|
34619
35137
|
log("Session result error:", turnSid, JSON.stringify({ subtype: r.subtype, stop_reason: r.stop_reason, errors, looksTransient }));
|
|
34620
35138
|
live.resultErrorReported = true;
|
|
34621
|
-
|
|
34622
|
-
|
|
35139
|
+
const recovered = contextHit === "context_window" && await this.recoverContextOverflow(live, turnSid);
|
|
35140
|
+
if (!recovered) {
|
|
35141
|
+
emit2({ type: "chat:error", sessionId: turnSid, error: detail, ...contextHit ? { continuable: true, continueReason: contextHit } : looksTransient ? { transient: true } : {} });
|
|
35142
|
+
emit2({ type: "agent:status", sessionId: turnSid, status: contextHit ? "idle" : "error" });
|
|
35143
|
+
}
|
|
34623
35144
|
}
|
|
34624
35145
|
blockAcc.clear();
|
|
34625
35146
|
insideXmlByKey.clear();
|
|
@@ -35678,6 +36199,9 @@ __export(dist_exports2, {
|
|
|
35678
36199
|
DesignTokensSchema: () => DesignTokensSchema,
|
|
35679
36200
|
DtcgTokensSchema: () => DtcgTokensSchema,
|
|
35680
36201
|
HookBus: () => HookBus,
|
|
36202
|
+
OVERFLOW_COMPACT_MESSAGE: () => OVERFLOW_COMPACT_MESSAGE,
|
|
36203
|
+
OVERFLOW_MAX_TRIES: () => OVERFLOW_MAX_TRIES,
|
|
36204
|
+
OVERFLOW_RESUME_MESSAGE: () => OVERFLOW_RESUME_MESSAGE,
|
|
35681
36205
|
PRESENT_TOOL_NAMES: () => PRESENT_TOOL_NAMES,
|
|
35682
36206
|
PRESENT_TOOL_SPECS: () => PRESENT_TOOL_SPECS,
|
|
35683
36207
|
SCREEN_CONTROL_SPECS: () => SCREEN_CONTROL_SPECS,
|
|
@@ -35691,6 +36215,7 @@ __export(dist_exports2, {
|
|
|
35691
36215
|
appendImageArtifact: () => appendImageArtifact,
|
|
35692
36216
|
appendSurfaceArtifact: () => appendSurfaceArtifact,
|
|
35693
36217
|
applyDesignPack: () => applyDesignPack,
|
|
36218
|
+
autoCompactEnvFor: () => autoCompactEnvFor,
|
|
35694
36219
|
buildAppControlTools: () => buildAppControlTools,
|
|
35695
36220
|
buildClaudeNarrationLlm: () => buildClaudeNarrationLlm,
|
|
35696
36221
|
buildClaudeSmartLlm: () => buildClaudeSmartLlm,
|
|
@@ -35724,6 +36249,9 @@ __export(dist_exports2, {
|
|
|
35724
36249
|
normalizeTokens: () => normalizeTokens,
|
|
35725
36250
|
parseColorToRgb: () => parseColorToRgb,
|
|
35726
36251
|
readSessionArtifacts: () => readSessionArtifacts,
|
|
36252
|
+
readUnattendedDecisions: () => readUnattendedDecisions,
|
|
36253
|
+
recordUnattendedDecision: () => recordUnattendedDecision,
|
|
36254
|
+
recoverFromContextOverflow: () => recoverFromContextOverflow,
|
|
35727
36255
|
renderAppControlReference: () => renderAppControlReference,
|
|
35728
36256
|
resolveNodeExecutable: () => resolveNodeExecutable,
|
|
35729
36257
|
resolveOauthToken: () => resolveOauthToken,
|
|
@@ -35737,6 +36265,7 @@ __export(dist_exports2, {
|
|
|
35737
36265
|
setBrowserExtensionProbe: () => setBrowserExtensionProbe,
|
|
35738
36266
|
setTokenPath: () => setTokenPath,
|
|
35739
36267
|
setTokenSegments: () => setTokenSegments,
|
|
36268
|
+
setUnattendedLogSink: () => setUnattendedLogSink,
|
|
35740
36269
|
specParametersJsonSchema: () => specParametersJsonSchema,
|
|
35741
36270
|
stringifyValue: () => stringifyValue,
|
|
35742
36271
|
stripPromptPrefix: () => stripPromptPrefix,
|
|
@@ -35747,6 +36276,7 @@ __export(dist_exports2, {
|
|
|
35747
36276
|
toolSpecJsonSchema: () => specParametersJsonSchema,
|
|
35748
36277
|
transferSession: () => transferSession,
|
|
35749
36278
|
unattendedAnswer: () => unattendedAnswer,
|
|
36279
|
+
unattendedLogPath: () => unattendedLogPath,
|
|
35750
36280
|
unattendedModeFor: () => unattendedModeFor,
|
|
35751
36281
|
walkTokens: () => walkTokens,
|
|
35752
36282
|
wrapCtxTool: () => wrapCtxTool,
|
|
@@ -35759,6 +36289,8 @@ var init_dist5 = __esm({
|
|
|
35759
36289
|
init_session_store();
|
|
35760
36290
|
init_session_usage();
|
|
35761
36291
|
init_unattended();
|
|
36292
|
+
init_unattended_log();
|
|
36293
|
+
init_context_recovery();
|
|
35762
36294
|
init_session_transfer();
|
|
35763
36295
|
init_log();
|
|
35764
36296
|
init_kill_tree();
|
|
@@ -35789,7 +36321,7 @@ __export(tesseract_mcp_endpoint_exports, {
|
|
|
35789
36321
|
startTesseractMcpEndpoint: () => startTesseractMcpEndpoint
|
|
35790
36322
|
});
|
|
35791
36323
|
import { createServer as createServer3 } from "node:http";
|
|
35792
|
-
import { readFileSync as
|
|
36324
|
+
import { readFileSync as readFileSync16, writeFileSync as writeFileSync11 } from "node:fs";
|
|
35793
36325
|
import { join as join20 } from "node:path";
|
|
35794
36326
|
function readBody2(req, limitBytes = 4 * 1024 * 1024) {
|
|
35795
36327
|
return new Promise((resolve16, reject) => {
|
|
@@ -35818,7 +36350,7 @@ function portFile() {
|
|
|
35818
36350
|
}
|
|
35819
36351
|
function rememberedPort() {
|
|
35820
36352
|
try {
|
|
35821
|
-
const o = JSON.parse(
|
|
36353
|
+
const o = JSON.parse(readFileSync16(portFile(), "utf8"));
|
|
35822
36354
|
return typeof o.port === "number" && o.port > 1024 ? o.port : 0;
|
|
35823
36355
|
} catch {
|
|
35824
36356
|
return 0;
|
|
@@ -35959,7 +36491,7 @@ __export(serpapi_runner_exports, {
|
|
|
35959
36491
|
createDaemonSerpClient: () => createDaemonSerpClient,
|
|
35960
36492
|
resolveSerpCreds: () => resolveSerpCreds
|
|
35961
36493
|
});
|
|
35962
|
-
import { existsSync as
|
|
36494
|
+
import { existsSync as existsSync10, readFileSync as readFileSync17 } from "node:fs";
|
|
35963
36495
|
function resolveSerpCreds() {
|
|
35964
36496
|
const snap = readDaemonAgentSettings().serp;
|
|
35965
36497
|
if (snap?.apiKey?.trim()) {
|
|
@@ -35974,8 +36506,8 @@ function resolveSerpCreds() {
|
|
|
35974
36506
|
};
|
|
35975
36507
|
}
|
|
35976
36508
|
const file2 = daemonPath("serpapi.key");
|
|
35977
|
-
if (
|
|
35978
|
-
const k =
|
|
36509
|
+
if (existsSync10(file2)) {
|
|
36510
|
+
const k = readFileSync17(file2, "utf-8").trim();
|
|
35979
36511
|
if (k)
|
|
35980
36512
|
return { apiKey: k, tier: "own", source: "key-file" };
|
|
35981
36513
|
}
|
|
@@ -62997,8 +63529,8 @@ var require_selfsigned = __commonJS({
|
|
|
62997
63529
|
// ../../packages/host-core/dist/peer-link/tls-direct.js
|
|
62998
63530
|
import tls from "node:tls";
|
|
62999
63531
|
import { X509Certificate, timingSafeEqual as timingSafeEqual2 } from "node:crypto";
|
|
63000
|
-
import { readFileSync as
|
|
63001
|
-
import { dirname as
|
|
63532
|
+
import { readFileSync as readFileSync33, writeFileSync as writeFileSync22, existsSync as existsSync20, mkdirSync as mkdirSync23 } from "node:fs";
|
|
63533
|
+
import { dirname as dirname18 } from "node:path";
|
|
63002
63534
|
function fingerprintOf(certPem) {
|
|
63003
63535
|
return new X509Certificate(certPem).fingerprint256;
|
|
63004
63536
|
}
|
|
@@ -63010,15 +63542,15 @@ function fingerprintsEqual(a, b) {
|
|
|
63010
63542
|
return ba.length === bb.length && timingSafeEqual2(ba, bb);
|
|
63011
63543
|
}
|
|
63012
63544
|
async function loadOrCreateIdentity(certPath, keyPath) {
|
|
63013
|
-
if (
|
|
63014
|
-
const cert =
|
|
63015
|
-
const key2 =
|
|
63545
|
+
if (existsSync20(certPath) && existsSync20(keyPath)) {
|
|
63546
|
+
const cert = readFileSync33(certPath, "utf8");
|
|
63547
|
+
const key2 = readFileSync33(keyPath, "utf8");
|
|
63016
63548
|
return { cert, key: key2, fingerprint256: fingerprintOf(cert) };
|
|
63017
63549
|
}
|
|
63018
63550
|
const tenYears = new Date(Date.now() + 10 * 365 * 24 * 60 * 60 * 1e3);
|
|
63019
63551
|
const pems = await (0, import_selfsigned.generate)([{ name: "commonName", value: "tesseract-peer" }], { keySize: 2048, notAfterDate: tenYears, algorithm: "sha256" });
|
|
63020
63552
|
try {
|
|
63021
|
-
|
|
63553
|
+
mkdirSync23(dirname18(certPath), { recursive: true });
|
|
63022
63554
|
} catch {
|
|
63023
63555
|
}
|
|
63024
63556
|
try {
|
|
@@ -70813,7 +71345,7 @@ var mesh_ca_exports = {};
|
|
|
70813
71345
|
__export(mesh_ca_exports, {
|
|
70814
71346
|
netCaCommand: () => netCaCommand
|
|
70815
71347
|
});
|
|
70816
|
-
import { chmodSync as chmodSync8, existsSync as
|
|
71348
|
+
import { chmodSync as chmodSync8, existsSync as existsSync42, mkdirSync as mkdirSync42, readFileSync as readFileSync48, writeFileSync as writeFileSync42 } from "node:fs";
|
|
70817
71349
|
import { join as join76, resolve as resolve13 } from "node:path";
|
|
70818
71350
|
import { createInterface } from "node:readline";
|
|
70819
71351
|
function die(msg) {
|
|
@@ -70852,7 +71384,7 @@ function writeSecretFile(p, bytes2) {
|
|
|
70852
71384
|
}
|
|
70853
71385
|
}
|
|
70854
71386
|
function ensureDir(p) {
|
|
70855
|
-
|
|
71387
|
+
mkdirSync42(p, { recursive: true, mode: 448 });
|
|
70856
71388
|
try {
|
|
70857
71389
|
chmodSync8(p, 448);
|
|
70858
71390
|
} catch {
|
|
@@ -70861,12 +71393,12 @@ function ensureDir(p) {
|
|
|
70861
71393
|
async function openCa(dir2) {
|
|
70862
71394
|
const gPath = join76(dir2, "genesis.bin");
|
|
70863
71395
|
const sPath = join76(dir2, "ca.sealed");
|
|
70864
|
-
if (!
|
|
71396
|
+
if (!existsSync42(gPath) || !existsSync42(sPath)) {
|
|
70865
71397
|
die(`No mesh CA in ${dir2}. Run: tesseract-agent net init --org NAME --ca-dir ${dir2}`);
|
|
70866
71398
|
}
|
|
70867
|
-
const genesisBytes = new Uint8Array(
|
|
71399
|
+
const genesisBytes = new Uint8Array(readFileSync48(gPath));
|
|
70868
71400
|
const genesis = decodeGenesis(genesisBytes);
|
|
70869
|
-
const sealed = decodeRecoveryBundle(new Uint8Array(
|
|
71401
|
+
const sealed = decodeRecoveryBundle(new Uint8Array(readFileSync48(sPath)));
|
|
70870
71402
|
const pass = await readPassphrase("CA passphrase: ");
|
|
70871
71403
|
let seed;
|
|
70872
71404
|
try {
|
|
@@ -70882,7 +71414,7 @@ async function netCaCommand(rest, flags) {
|
|
|
70882
71414
|
if (sub === "init") {
|
|
70883
71415
|
const org = typeof flags.org === "string" ? flags.org.trim() : "";
|
|
70884
71416
|
if (!org) die("Usage: tesseract-agent net init --org NAME [--ca-dir DIR]");
|
|
70885
|
-
if (
|
|
71417
|
+
if (existsSync42(join76(caDir, "ca.sealed"))) {
|
|
70886
71418
|
die(`A mesh CA already exists in ${caDir}. Refusing to overwrite it.`);
|
|
70887
71419
|
}
|
|
70888
71420
|
const pass = await readPassphrase("New CA passphrase: ");
|
|
@@ -71040,12 +71572,12 @@ var init_mesh_ca = __esm({
|
|
|
71040
71572
|
|
|
71041
71573
|
// src/cli.ts
|
|
71042
71574
|
init_base_paths();
|
|
71043
|
-
import { existsSync as
|
|
71575
|
+
import { existsSync as existsSync43, mkdtempSync as mkdtempSync2, readFileSync as readFileSync50, rmSync as rmSync11 } from "node:fs";
|
|
71044
71576
|
import { createHash as createHash8 } from "node:crypto";
|
|
71045
71577
|
import { execFileSync as execFileSync6, spawn as spawn16 } from "node:child_process";
|
|
71046
71578
|
import { fileURLToPath as fileURLToPath6 } from "node:url";
|
|
71047
71579
|
import { tmpdir as tmpdir6 } from "node:os";
|
|
71048
|
-
import { dirname as
|
|
71580
|
+
import { dirname as dirname32, join as join77, resolve as resolve15 } from "node:path";
|
|
71049
71581
|
import { createInterface as createInterface2 } from "node:readline/promises";
|
|
71050
71582
|
|
|
71051
71583
|
// ../../packages/host-core/dist/control-link.js
|
|
@@ -71075,7 +71607,7 @@ function toRewindOutcome(res, noHistory) {
|
|
|
71075
71607
|
// ../../packages/host-core/dist/control-link.js
|
|
71076
71608
|
import { join as join53, basename as basename11 } from "node:path";
|
|
71077
71609
|
import { randomUUID as randomUUID22 } from "node:crypto";
|
|
71078
|
-
import { mkdirSync as
|
|
71610
|
+
import { mkdirSync as mkdirSync27 } from "node:fs";
|
|
71079
71611
|
|
|
71080
71612
|
// ../../node_modules/ws/wrapper.mjs
|
|
71081
71613
|
var import_stream = __toESM(require_stream(), 1);
|
|
@@ -72384,6 +72916,7 @@ async function createClaudeCodeBackend(send4, onBrowserRequest, loadPluginRuntim
|
|
|
72384
72916
|
send4(msg, origin);
|
|
72385
72917
|
};
|
|
72386
72918
|
const manager2 = new AgentManager2(sendWatchingSessions, onBrowserRequest);
|
|
72919
|
+
manager2.setAutoCompactPct(() => readDaemonAgentSettings().autoCompactPct);
|
|
72387
72920
|
const claudeSnapshots = createSnapshotStore(join19(daemonDir(), "engine-snapshots", "claude-code.json"));
|
|
72388
72921
|
const claudeTurnSeq = /* @__PURE__ */ new Map();
|
|
72389
72922
|
const pendingAlias = /* @__PURE__ */ new Map();
|
|
@@ -73162,7 +73695,7 @@ function geminiMessageText(m) {
|
|
|
73162
73695
|
}
|
|
73163
73696
|
|
|
73164
73697
|
// ../../packages/host-core/dist/engines/hosted-verification.js
|
|
73165
|
-
function createHostedVerification() {
|
|
73698
|
+
function createHostedVerification(engineId) {
|
|
73166
73699
|
let verifier = null;
|
|
73167
73700
|
return {
|
|
73168
73701
|
setVerifier: (fn) => {
|
|
@@ -73171,6 +73704,7 @@ function createHostedVerification() {
|
|
|
73171
73704
|
canGrade: () => verifier !== null,
|
|
73172
73705
|
async run({ sessionId, task, finalText, todos, reprompt, emit: emit2, model, clientRequestId, cancelled }) {
|
|
73173
73706
|
const rv = await Promise.resolve().then(() => (init_reinforced_verification(), reinforced_verification_exports));
|
|
73707
|
+
const ulog = await Promise.resolve().then(() => (init_unattended_log(), unattended_log_exports));
|
|
73174
73708
|
const base = { type: "agent:verification", sessionId, ...clientRequestId ? { clientRequestId } : {}, maxCycles: rv.RV_MAX_CYCLES };
|
|
73175
73709
|
const standDown = (cycle, unavailable) => {
|
|
73176
73710
|
emit2({ ...base, action: "done", gate: "completeness", cycle, unavailable });
|
|
@@ -73189,11 +73723,14 @@ function createHostedVerification() {
|
|
|
73189
73723
|
}
|
|
73190
73724
|
const grade = verifier;
|
|
73191
73725
|
let state3 = rv.newRvState(task);
|
|
73726
|
+
if (finalText.trim())
|
|
73727
|
+
state3 = { ...state3, plan: finalText.slice(0, 4e3) };
|
|
73192
73728
|
let text9 = finalText;
|
|
73193
73729
|
let reviewText = "";
|
|
73194
|
-
|
|
73195
|
-
|
|
73196
|
-
const
|
|
73730
|
+
let phaseText = "";
|
|
73731
|
+
for (let i = 0; i < rv.RV_MAX_CYCLES * 5 + 4; i++) {
|
|
73732
|
+
const gate = state3.phase === "review" ? "review" : state3.phase === "phase-review" ? "phase" : "completeness";
|
|
73733
|
+
const call3 = gate === "review" ? rv.reviewGrade(state3, reviewText || text9, todos) : gate === "phase" ? rv.phaseGrade(state3, state3.lastVerdict?.phaseName ?? "", phaseText || text9, todos) : rv.completenessGrade(state3, text9, todos);
|
|
73197
73734
|
let verdict = null;
|
|
73198
73735
|
try {
|
|
73199
73736
|
verdict = rv.parseVerdict(await grade({ model, system: call3.system, prompt: call3.prompt, maxTokens: 16e3, schema: call3.schema }));
|
|
@@ -73214,6 +73751,20 @@ function createHostedVerification() {
|
|
|
73214
73751
|
const action = rv.rvDecision(verdict, state3);
|
|
73215
73752
|
state3 = rv.rvAdvance(state3, action, verdict);
|
|
73216
73753
|
emit2({ ...base, action: action.kind, gate, cycle: state3.cycles, verdict });
|
|
73754
|
+
ulog.recordVerificationDecision({
|
|
73755
|
+
sessionId,
|
|
73756
|
+
...engineId ? { engine: engineId } : {},
|
|
73757
|
+
gate,
|
|
73758
|
+
action: action.kind,
|
|
73759
|
+
cycle: state3.cycles,
|
|
73760
|
+
phasesDone: state3.phasesDone,
|
|
73761
|
+
phaseName: verdict.phaseName,
|
|
73762
|
+
taskComplete: verdict.taskComplete,
|
|
73763
|
+
phaseComplete: verdict.phaseComplete,
|
|
73764
|
+
exercised: verdict.exercised,
|
|
73765
|
+
blocking: rv.blockingIssues(verdict).length,
|
|
73766
|
+
summary: verdict.summary
|
|
73767
|
+
});
|
|
73217
73768
|
if (action.kind === "done" || action.kind === "capped")
|
|
73218
73769
|
return text9;
|
|
73219
73770
|
try {
|
|
@@ -73224,15 +73775,18 @@ function createHostedVerification() {
|
|
|
73224
73775
|
return text9;
|
|
73225
73776
|
}
|
|
73226
73777
|
}
|
|
73227
|
-
const before = action.kind === "review" ? reviewText : text9;
|
|
73778
|
+
const before = action.kind === "review" ? reviewText : action.kind === "phase-review" ? phaseText : text9;
|
|
73228
73779
|
const reply3 = await reprompt(action.prompt);
|
|
73229
73780
|
if (!reply3 || reply3 === before) {
|
|
73230
73781
|
standDown(state3.cycles, "The agent did not produce anything new when sent back, so this run was not verified.");
|
|
73231
73782
|
return text9;
|
|
73232
73783
|
}
|
|
73233
|
-
if (action.kind
|
|
73784
|
+
if (action.kind === "review")
|
|
73785
|
+
reviewText = reply3;
|
|
73786
|
+
else if (action.kind === "phase-review")
|
|
73787
|
+
phaseText = reply3;
|
|
73788
|
+
else
|
|
73234
73789
|
text9 = reply3;
|
|
73235
|
-
reviewText = action.kind === "review" ? reply3 : reviewText;
|
|
73236
73790
|
} catch {
|
|
73237
73791
|
standDown(state3.cycles, "Verification could not be completed, so this run was not verified.");
|
|
73238
73792
|
return text9;
|
|
@@ -73246,7 +73800,7 @@ function createHostedVerification() {
|
|
|
73246
73800
|
|
|
73247
73801
|
// ../../packages/host-core/dist/engines/model-pricing.js
|
|
73248
73802
|
init_credentials();
|
|
73249
|
-
import { readFileSync as
|
|
73803
|
+
import { readFileSync as readFileSync18, writeFileSync as writeFileSync12 } from "node:fs";
|
|
73250
73804
|
import { join as join22 } from "node:path";
|
|
73251
73805
|
var LITELLM_URL = "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json";
|
|
73252
73806
|
var MODELS_DEV_URL = "https://models.dev/api.json";
|
|
@@ -73278,7 +73832,7 @@ var Source = class {
|
|
|
73278
73832
|
if (this.data || this.pinned)
|
|
73279
73833
|
return;
|
|
73280
73834
|
try {
|
|
73281
|
-
const o = JSON.parse(
|
|
73835
|
+
const o = JSON.parse(readFileSync18(this.path, "utf8"));
|
|
73282
73836
|
if (o.map && this.sane(o.map)) {
|
|
73283
73837
|
this.data = o.map;
|
|
73284
73838
|
this.fetchedAt = o.fetchedAt ?? 0;
|
|
@@ -73577,7 +74131,7 @@ var AcpTransport = class {
|
|
|
73577
74131
|
import { spawn as spawn5 } from "node:child_process";
|
|
73578
74132
|
import { mkdir as mkdir5, readFile as readFile8, writeFile as writeFile6 } from "node:fs/promises";
|
|
73579
74133
|
import { realpathSync as realpathSync3 } from "node:fs";
|
|
73580
|
-
import { basename as basename3, dirname as
|
|
74134
|
+
import { basename as basename3, dirname as dirname9, isAbsolute as isAbsolute4, resolve as resolve6, sep as sep4 } from "node:path";
|
|
73581
74135
|
var DEFAULT_OUTPUT_BYTE_LIMIT = 1024 * 1024;
|
|
73582
74136
|
var MAX_OUTPUT_BYTE_LIMIT = 8 * 1024 * 1024;
|
|
73583
74137
|
var MAX_TERMINALS = 16;
|
|
@@ -73597,7 +74151,7 @@ function realpathDeep(abs) {
|
|
|
73597
74151
|
return tail3.length ? resolve6(real, ...tail3) : real;
|
|
73598
74152
|
} catch {
|
|
73599
74153
|
}
|
|
73600
|
-
const parent =
|
|
74154
|
+
const parent = dirname9(head);
|
|
73601
74155
|
if (parent === head)
|
|
73602
74156
|
return abs;
|
|
73603
74157
|
tail3.unshift(basename3(head));
|
|
@@ -73665,7 +74219,7 @@ function installWorkspaceHandlers(t, opts) {
|
|
|
73665
74219
|
if (!target)
|
|
73666
74220
|
return null;
|
|
73667
74221
|
const content = p.content ?? "";
|
|
73668
|
-
await mkdir5(
|
|
74222
|
+
await mkdir5(dirname9(target), { recursive: true }).catch(() => {
|
|
73669
74223
|
});
|
|
73670
74224
|
await writeFile6(target, content, "utf8").catch(() => {
|
|
73671
74225
|
});
|
|
@@ -73784,9 +74338,9 @@ function installWorkspaceHandlers(t, opts) {
|
|
|
73784
74338
|
}
|
|
73785
74339
|
|
|
73786
74340
|
// ../../packages/host-core/dist/engines/mcp-injection.js
|
|
73787
|
-
import { copyFileSync as copyFileSync2, existsSync as
|
|
74341
|
+
import { copyFileSync as copyFileSync2, existsSync as existsSync11, mkdirSync as mkdirSync12, readFileSync as readFileSync19, readdirSync as readdirSync3, symlinkSync as symlinkSync2, writeFileSync as writeFileSync13 } from "node:fs";
|
|
73788
74342
|
import { homedir as homedir6 } from "node:os";
|
|
73789
|
-
import { dirname as
|
|
74343
|
+
import { dirname as dirname10, join as join23, resolve as resolve7 } from "node:path";
|
|
73790
74344
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
73791
74345
|
var BUNDLED_MCP_SERVERS = [
|
|
73792
74346
|
{ name: "tesseract-serp", basename: "serpapi-mcp.js", envOverride: "CCB_SERPAPI_MCP_JS" }
|
|
@@ -73804,7 +74358,7 @@ function resolveBundledMcpBin(basename14, envOverride) {
|
|
|
73804
74358
|
if (rp)
|
|
73805
74359
|
candidates.push(join23(rp, "host-daemon", basename14));
|
|
73806
74360
|
try {
|
|
73807
|
-
const here =
|
|
74361
|
+
const here = dirname10(fileURLToPath2(import.meta.url));
|
|
73808
74362
|
candidates.push(join23(here, basename14));
|
|
73809
74363
|
candidates.push(resolve7(here, "../../../../apps/host-daemon/dist-bundle", basename14));
|
|
73810
74364
|
candidates.push(resolve7(here, "../../../../apps/host-daemon/dist", basename14));
|
|
@@ -73812,7 +74366,7 @@ function resolveBundledMcpBin(basename14, envOverride) {
|
|
|
73812
74366
|
} catch {
|
|
73813
74367
|
}
|
|
73814
74368
|
for (const c of candidates) {
|
|
73815
|
-
if (
|
|
74369
|
+
if (existsSync11(c)) {
|
|
73816
74370
|
resolvedBins.set(basename14, c);
|
|
73817
74371
|
return c;
|
|
73818
74372
|
}
|
|
@@ -73874,7 +74428,7 @@ function specToSettingsServer(spec) {
|
|
|
73874
74428
|
}
|
|
73875
74429
|
function readJson(path6) {
|
|
73876
74430
|
try {
|
|
73877
|
-
return JSON.parse(
|
|
74431
|
+
return JSON.parse(readFileSync19(path6, "utf8"));
|
|
73878
74432
|
} catch {
|
|
73879
74433
|
return {};
|
|
73880
74434
|
}
|
|
@@ -73883,9 +74437,9 @@ function writeManagedMcpHome(engineId, layout, servers, projectDir, baseDir, use
|
|
|
73883
74437
|
try {
|
|
73884
74438
|
const home = join23(baseDir, "engine-mcp-home", engineId);
|
|
73885
74439
|
const cfg2 = join23(home, layout.configDir);
|
|
73886
|
-
|
|
74440
|
+
mkdirSync12(cfg2, { recursive: true });
|
|
73887
74441
|
if (layout.linkSiblingConfigs) {
|
|
73888
|
-
const realRoot =
|
|
74442
|
+
const realRoot = dirname10(join23(userHome2, layout.userConfigDirRel ?? layout.configDir));
|
|
73889
74443
|
let entries = [];
|
|
73890
74444
|
try {
|
|
73891
74445
|
entries = readdirSync3(realRoot);
|
|
@@ -73896,7 +74450,7 @@ function writeManagedMcpHome(engineId, layout, servers, projectDir, baseDir, use
|
|
|
73896
74450
|
if (name === layout.configDir)
|
|
73897
74451
|
continue;
|
|
73898
74452
|
const link = join23(home, name);
|
|
73899
|
-
if (
|
|
74453
|
+
if (existsSync11(link))
|
|
73900
74454
|
continue;
|
|
73901
74455
|
try {
|
|
73902
74456
|
symlinkSync2(join23(realRoot, name), link);
|
|
@@ -73920,7 +74474,7 @@ function writeManagedMcpHome(engineId, layout, servers, projectDir, baseDir, use
|
|
|
73920
74474
|
if ((layout.seedFiles ?? []).includes(name))
|
|
73921
74475
|
continue;
|
|
73922
74476
|
const link = join23(cfg2, name);
|
|
73923
|
-
if (
|
|
74477
|
+
if (existsSync11(link))
|
|
73924
74478
|
continue;
|
|
73925
74479
|
try {
|
|
73926
74480
|
symlinkSync2(join23(userCfg, name), link);
|
|
@@ -73931,7 +74485,7 @@ function writeManagedMcpHome(engineId, layout, servers, projectDir, baseDir, use
|
|
|
73931
74485
|
for (const f of layout.seedFiles ?? []) {
|
|
73932
74486
|
const src = join23(userCfg, f);
|
|
73933
74487
|
const dst = join23(cfg2, f);
|
|
73934
|
-
if (
|
|
74488
|
+
if (existsSync11(src) && !existsSync11(dst)) {
|
|
73935
74489
|
try {
|
|
73936
74490
|
copyFileSync2(src, dst);
|
|
73937
74491
|
} catch {
|
|
@@ -73940,7 +74494,7 @@ function writeManagedMcpHome(engineId, layout, servers, projectDir, baseDir, use
|
|
|
73940
74494
|
}
|
|
73941
74495
|
for (const f of layout.mirrorFiles ?? []) {
|
|
73942
74496
|
const src = join23(userCfg, f);
|
|
73943
|
-
if (!
|
|
74497
|
+
if (!existsSync11(src))
|
|
73944
74498
|
continue;
|
|
73945
74499
|
try {
|
|
73946
74500
|
copyFileSync2(src, join23(cfg2, f));
|
|
@@ -74537,7 +75091,7 @@ function httpApiArgs(spec, port) {
|
|
|
74537
75091
|
}
|
|
74538
75092
|
|
|
74539
75093
|
// ../../packages/host-core/dist/engines/session-index.js
|
|
74540
|
-
import { mkdirSync as
|
|
75094
|
+
import { mkdirSync as mkdirSync13, readFileSync as readFileSync20, writeFileSync as writeFileSync14 } from "node:fs";
|
|
74541
75095
|
import { join as join24 } from "node:path";
|
|
74542
75096
|
var MAX_ROWS = 500;
|
|
74543
75097
|
function createSessionIndex(engineId, baseDir, now2 = Date.now) {
|
|
@@ -74547,7 +75101,7 @@ function createSessionIndex(engineId, baseDir, now2 = Date.now) {
|
|
|
74547
75101
|
if (rows)
|
|
74548
75102
|
return rows;
|
|
74549
75103
|
try {
|
|
74550
|
-
const parsed = JSON.parse(
|
|
75104
|
+
const parsed = JSON.parse(readFileSync20(file2, "utf8"));
|
|
74551
75105
|
rows = (parsed.sessions ?? []).filter((r) => r && typeof r.id === "string");
|
|
74552
75106
|
} catch {
|
|
74553
75107
|
rows = [];
|
|
@@ -74561,7 +75115,7 @@ function createSessionIndex(engineId, baseDir, now2 = Date.now) {
|
|
|
74561
75115
|
if (rows.length > MAX_ROWS)
|
|
74562
75116
|
rows = rows.slice(0, MAX_ROWS);
|
|
74563
75117
|
try {
|
|
74564
|
-
|
|
75118
|
+
mkdirSync13(join24(baseDir, "engine-sessions"), { recursive: true });
|
|
74565
75119
|
writeFileSync14(file2, JSON.stringify({ sessions: rows }, null, 2), { mode: 384 });
|
|
74566
75120
|
} catch {
|
|
74567
75121
|
}
|
|
@@ -74637,7 +75191,7 @@ function wrapWithSeatbelt(command, args, profile) {
|
|
|
74637
75191
|
|
|
74638
75192
|
// ../../packages/host-core/dist/engines/opencode-acp.js
|
|
74639
75193
|
init_dist5();
|
|
74640
|
-
import { mkdirSync as
|
|
75194
|
+
import { mkdirSync as mkdirSync14, writeFileSync as writeFileSync15, readFileSync as readFileSync21 } from "node:fs";
|
|
74641
75195
|
import { join as join25, relative as relative4 } from "node:path";
|
|
74642
75196
|
import { homedir as homedir7, tmpdir as tmpdir4 } from "node:os";
|
|
74643
75197
|
var TESSERACT_INTERNAL_SECRET2 = /^(CCB_JWT_SECRET|JWT_SECRET|TESSERACT_TOKEN|CCB_RELAY_SECRET|TURN_SECRET|LIVEKIT_API_SECRET)$/;
|
|
@@ -74686,7 +75240,7 @@ function modelMemoPath(engineId) {
|
|
|
74686
75240
|
}
|
|
74687
75241
|
function lastKnownModel(engineId) {
|
|
74688
75242
|
try {
|
|
74689
|
-
return
|
|
75243
|
+
return readFileSync21(modelMemoPath(engineId), "utf8").trim() || void 0;
|
|
74690
75244
|
} catch {
|
|
74691
75245
|
return void 0;
|
|
74692
75246
|
}
|
|
@@ -74695,7 +75249,7 @@ function rememberModel(engineId, modelId) {
|
|
|
74695
75249
|
if (!modelId || modelId === lastKnownModel(engineId))
|
|
74696
75250
|
return;
|
|
74697
75251
|
try {
|
|
74698
|
-
|
|
75252
|
+
mkdirSync14(join25(daemonDir2(), "engine-config", engineId), { recursive: true });
|
|
74699
75253
|
writeFileSync15(modelMemoPath(engineId), modelId, { mode: 384 });
|
|
74700
75254
|
} catch {
|
|
74701
75255
|
}
|
|
@@ -74711,7 +75265,7 @@ async function writeTokenCompactionConfig(engineId, spec, modelId, pct2, baseDir
|
|
|
74711
75265
|
return {};
|
|
74712
75266
|
try {
|
|
74713
75267
|
const dir2 = join25(baseDir, "engine-config", engineId);
|
|
74714
|
-
|
|
75268
|
+
mkdirSync14(dir2, { recursive: true });
|
|
74715
75269
|
const file2 = join25(dir2, "tesseract.json");
|
|
74716
75270
|
const cfg2 = {};
|
|
74717
75271
|
let node = cfg2;
|
|
@@ -75082,7 +75636,7 @@ function createAcpBackend(engine, send4, resolve16, onBrowserRequest, loadPlugin
|
|
|
75082
75636
|
let hostTasks = null;
|
|
75083
75637
|
let refreshHostedTools = null;
|
|
75084
75638
|
const lastTurnText = /* @__PURE__ */ new Map();
|
|
75085
|
-
const verification = createHostedVerification();
|
|
75639
|
+
const verification = createHostedVerification(engine.id);
|
|
75086
75640
|
const scheduling = createHostedScheduling(async (task) => {
|
|
75087
75641
|
const pol = scheduling.policy();
|
|
75088
75642
|
try {
|
|
@@ -75133,10 +75687,10 @@ function createAcpBackend(engine, send4, resolve16, onBrowserRequest, loadPlugin
|
|
|
75133
75687
|
collectReplay(replay, u);
|
|
75134
75688
|
return;
|
|
75135
75689
|
}
|
|
75136
|
-
const
|
|
75137
|
-
if (
|
|
75690
|
+
const sink2 = subagentSinks.get(sid);
|
|
75691
|
+
if (sink2) {
|
|
75138
75692
|
if (u.sessionUpdate === "agent_message_chunk")
|
|
75139
|
-
|
|
75693
|
+
sink2.push(u.content?.text ?? "");
|
|
75140
75694
|
return;
|
|
75141
75695
|
}
|
|
75142
75696
|
if (u.sessionUpdate === "usage_update") {
|
|
@@ -75257,6 +75811,7 @@ function createAcpBackend(engine, send4, resolve16, onBrowserRequest, loadPlugin
|
|
|
75257
75811
|
if (!turn)
|
|
75258
75812
|
return;
|
|
75259
75813
|
scheduleUnattendedAnswer({ kind: "elicitation", serverName: engine.label }, {
|
|
75814
|
+
context: { sessionId: sid, engine: engine.id },
|
|
75260
75815
|
mode: () => turn.unattended,
|
|
75261
75816
|
charge: () => turn.autoDecisions += 1,
|
|
75262
75817
|
refund: () => {
|
|
@@ -75434,6 +75989,7 @@ function createAcpBackend(engine, send4, resolve16, onBrowserRequest, loadPlugin
|
|
|
75434
75989
|
}, turn?.origin);
|
|
75435
75990
|
if (turn) {
|
|
75436
75991
|
scheduleUnattendedAnswer({ kind: "permission", tool: toolName }, {
|
|
75992
|
+
context: { sessionId: psid, engine: engine.id },
|
|
75437
75993
|
mode: () => turn.unattended,
|
|
75438
75994
|
charge: () => turn.autoDecisions += 1,
|
|
75439
75995
|
refund: () => {
|
|
@@ -75493,6 +76049,7 @@ function createAcpBackend(engine, send4, resolve16, onBrowserRequest, loadPlugin
|
|
|
75493
76049
|
if (!turn)
|
|
75494
76050
|
return;
|
|
75495
76051
|
scheduleUnattendedAnswer({ kind: "elicitation", serverName: "connector" }, {
|
|
76052
|
+
context: { sessionId: esid, engine: engine.id },
|
|
75496
76053
|
mode: () => turn.unattended,
|
|
75497
76054
|
charge: () => turn.autoDecisions += 1,
|
|
75498
76055
|
refund: () => {
|
|
@@ -75780,11 +76337,11 @@ ${text9}`);
|
|
|
75780
76337
|
await replayLoad(conn, sessionId);
|
|
75781
76338
|
}
|
|
75782
76339
|
async function promptForText(t, sid, prompt) {
|
|
75783
|
-
const
|
|
75784
|
-
subagentSinks.set(sid,
|
|
76340
|
+
const sink2 = [];
|
|
76341
|
+
subagentSinks.set(sid, sink2);
|
|
75785
76342
|
try {
|
|
75786
76343
|
for (let attempt = 0; attempt < RESEED_SUMMARY_ATTEMPTS; attempt++) {
|
|
75787
|
-
|
|
76344
|
+
sink2.length = 0;
|
|
75788
76345
|
let timer2;
|
|
75789
76346
|
const timedOut = Symbol("timeout");
|
|
75790
76347
|
const outcome = await Promise.race([
|
|
@@ -75807,7 +76364,7 @@ ${text9}`);
|
|
|
75807
76364
|
}
|
|
75808
76365
|
return null;
|
|
75809
76366
|
}
|
|
75810
|
-
const out =
|
|
76367
|
+
const out = sink2.join("").trim();
|
|
75811
76368
|
if (out)
|
|
75812
76369
|
return out;
|
|
75813
76370
|
if (attempt < RESEED_SUMMARY_ATTEMPTS - 1)
|
|
@@ -75889,6 +76446,7 @@ ${text9}`);
|
|
|
75889
76446
|
const all = await listSessionsFor(projectDir);
|
|
75890
76447
|
return all.filter((row) => row.title.toLowerCase().includes(q) || (sessionBodies.get(row.id) ?? "").includes(q));
|
|
75891
76448
|
}
|
|
76449
|
+
const overflowTries = /* @__PURE__ */ new Map();
|
|
75892
76450
|
async function sendMessage(params) {
|
|
75893
76451
|
const origin = params.origin;
|
|
75894
76452
|
const fail4 = (sessionId, error51, transient = false) => send4({ type: "chat:error", sessionId, clientRequestId: params.clientRequestId, error: error51, ...transient ? { transient: true } : {} }, origin);
|
|
@@ -76163,6 +76721,7 @@ ${text9}`);
|
|
|
76163
76721
|
}
|
|
76164
76722
|
}
|
|
76165
76723
|
}
|
|
76724
|
+
overflowTries.delete(sid);
|
|
76166
76725
|
send4({ type: "chat:complete", sessionId: sid, clientRequestId: params.clientRequestId, messageId, result: finalText, turnId, ...res?.stopReason ? { stopReason: res.stopReason } : {} }, origin);
|
|
76167
76726
|
send4({ type: "agent:status", sessionId: sid, clientRequestId: params.clientRequestId, status: "idle" }, origin);
|
|
76168
76727
|
} catch (e) {
|
|
@@ -76170,6 +76729,19 @@ ${text9}`);
|
|
|
76170
76729
|
const detail = String(e?.message ?? e);
|
|
76171
76730
|
const overflow = isContextOverflow(detail);
|
|
76172
76731
|
if (overflow && declared.contextCompaction) {
|
|
76732
|
+
const recovered = await recoverFromContextOverflow({
|
|
76733
|
+
mode: () => unattendedModeFor({ optedIn: params.unattended, origin: params.origin }),
|
|
76734
|
+
canCompact: () => true,
|
|
76735
|
+
tries: () => overflowTries.get(sid) ?? 0,
|
|
76736
|
+
bump: () => overflowTries.set(sid, (overflowTries.get(sid) ?? 0) + 1),
|
|
76737
|
+
context: { sessionId: sid, engine: engine.id },
|
|
76738
|
+
compactAndResume: async () => {
|
|
76739
|
+
await sendMessage({ ...params, message: OVERFLOW_COMPACT_MESSAGE, sessionId: sid, autoContinuation: true });
|
|
76740
|
+
await sendMessage({ ...params, message: OVERFLOW_RESUME_MESSAGE, sessionId: sid, autoContinuation: true });
|
|
76741
|
+
}
|
|
76742
|
+
});
|
|
76743
|
+
if (recovered)
|
|
76744
|
+
return;
|
|
76173
76745
|
send4({ type: "chat:error", sessionId: sid, clientRequestId: params.clientRequestId, error: detail, continuable: true, continueReason: "context_window" }, origin);
|
|
76174
76746
|
send4({ type: "agent:status", sessionId: sid, clientRequestId: params.clientRequestId, status: "idle" }, origin);
|
|
76175
76747
|
return;
|
|
@@ -76889,7 +77461,7 @@ init_dist();
|
|
|
76889
77461
|
init_credentials();
|
|
76890
77462
|
import { spawn as spawn8 } from "node:child_process";
|
|
76891
77463
|
import { randomUUID as randomUUID12 } from "node:crypto";
|
|
76892
|
-
import { mkdirSync as
|
|
77464
|
+
import { mkdirSync as mkdirSync15, readFileSync as readFileSync22, writeFileSync as writeFileSync16 } from "node:fs";
|
|
76893
77465
|
import { join as join26 } from "node:path";
|
|
76894
77466
|
init_daemon_settings();
|
|
76895
77467
|
init_dist5();
|
|
@@ -77147,7 +77719,7 @@ function createCodexAppServerBackend(send4, resolve16, onBrowserRequest, loadPlu
|
|
|
77147
77719
|
let hostedBearer = null;
|
|
77148
77720
|
let refreshHostedTools = null;
|
|
77149
77721
|
const lastTurnText = /* @__PURE__ */ new Map();
|
|
77150
|
-
const verification = createHostedVerification();
|
|
77722
|
+
const verification = createHostedVerification("codex");
|
|
77151
77723
|
const scheduling = createHostedScheduling(async (task) => {
|
|
77152
77724
|
try {
|
|
77153
77725
|
await sendMessage({ message: task.prompt, url: "", projectDir: spawnedCwd ?? void 0, sessionId: task.sessionId, origin: "cron" });
|
|
@@ -77220,6 +77792,7 @@ function createCodexAppServerBackend(send4, resolve16, onBrowserRequest, loadPlu
|
|
|
77220
77792
|
if (!turn)
|
|
77221
77793
|
return;
|
|
77222
77794
|
scheduleUnattendedAnswer({ kind: "permission", tool: toolName }, {
|
|
77795
|
+
context: { sessionId: turn.threadId, engine: "codex" },
|
|
77223
77796
|
mode: () => turn.unattended,
|
|
77224
77797
|
charge: () => turn.autoDecisions += 1,
|
|
77225
77798
|
refund: () => {
|
|
@@ -77253,6 +77826,7 @@ function createCodexAppServerBackend(send4, resolve16, onBrowserRequest, loadPlu
|
|
|
77253
77826
|
if (!turn)
|
|
77254
77827
|
return;
|
|
77255
77828
|
scheduleUnattendedAnswer(prompt, {
|
|
77829
|
+
context: { sessionId: turn.threadId, engine: "codex" },
|
|
77256
77830
|
mode: () => turn.unattended,
|
|
77257
77831
|
charge: () => turn.autoDecisions += 1,
|
|
77258
77832
|
refund: () => {
|
|
@@ -77284,10 +77858,10 @@ function createCodexAppServerBackend(send4, resolve16, onBrowserRequest, loadPlu
|
|
|
77284
77858
|
function onNotification(method, raw) {
|
|
77285
77859
|
const p = raw ?? {};
|
|
77286
77860
|
const threadId = String(p.threadId ?? "");
|
|
77287
|
-
const
|
|
77288
|
-
if (
|
|
77861
|
+
const sink2 = subagentSinks.get(threadId);
|
|
77862
|
+
if (sink2) {
|
|
77289
77863
|
if (method === "item/agentMessage/delta")
|
|
77290
|
-
|
|
77864
|
+
sink2.push(String(p.delta ?? ""));
|
|
77291
77865
|
if (method === "turn/completed" || method === "error")
|
|
77292
77866
|
subagentDone.get(threadId)?.();
|
|
77293
77867
|
return;
|
|
@@ -77425,7 +77999,7 @@ function createCodexAppServerBackend(send4, resolve16, onBrowserRequest, loadPlu
|
|
|
77425
77999
|
lastWindow = window2;
|
|
77426
78000
|
try {
|
|
77427
78001
|
const dir2 = join26(daemonDir2(), "engine-config", "openai-codex");
|
|
77428
|
-
|
|
78002
|
+
mkdirSync15(dir2, { recursive: true });
|
|
77429
78003
|
writeFileSync16(join26(dir2, "window"), String(window2), { mode: 384 });
|
|
77430
78004
|
} catch {
|
|
77431
78005
|
}
|
|
@@ -77434,7 +78008,7 @@ function createCodexAppServerBackend(send4, resolve16, onBrowserRequest, loadPlu
|
|
|
77434
78008
|
if (lastWindow)
|
|
77435
78009
|
return lastWindow;
|
|
77436
78010
|
try {
|
|
77437
|
-
const n = Number(
|
|
78011
|
+
const n = Number(readFileSync22(join26(daemonDir2(), "engine-config", "openai-codex", "window"), "utf8").trim());
|
|
77438
78012
|
return Number.isFinite(n) && n > 0 ? lastWindow = n : void 0;
|
|
77439
78013
|
} catch {
|
|
77440
78014
|
return void 0;
|
|
@@ -77599,6 +78173,7 @@ function createCodexAppServerBackend(send4, resolve16, onBrowserRequest, loadPlu
|
|
|
77599
78173
|
})();
|
|
77600
78174
|
return initPromise;
|
|
77601
78175
|
}
|
|
78176
|
+
const overflowTries = /* @__PURE__ */ new Map();
|
|
77602
78177
|
async function sendMessage(params) {
|
|
77603
78178
|
const origin = params.origin;
|
|
77604
78179
|
const cfg2 = resolve16(ENGINE_ID2);
|
|
@@ -77788,12 +78363,27 @@ function createCodexAppServerBackend(send4, resolve16, onBrowserRequest, loadPlu
|
|
|
77788
78363
|
}
|
|
77789
78364
|
});
|
|
77790
78365
|
}
|
|
78366
|
+
overflowTries.delete(threadId);
|
|
77791
78367
|
send4({ type: "chat:complete", sessionId: threadId, clientRequestId: params.clientRequestId, messageId, result: finalText, turnId, ...stopReason ? { stopReason } : {} }, origin);
|
|
77792
78368
|
send4({ type: "agent:status", sessionId: threadId, clientRequestId: params.clientRequestId, status: "idle" }, origin);
|
|
77793
78369
|
} catch (e) {
|
|
77794
78370
|
turns.delete(threadId);
|
|
77795
78371
|
const detail = String(e?.message ?? e);
|
|
77796
78372
|
if (isContextOverflow(detail)) {
|
|
78373
|
+
const recovered = await recoverFromContextOverflow({
|
|
78374
|
+
mode: () => unattendedModeFor({ optedIn: params.unattended, origin: params.origin }),
|
|
78375
|
+
canCompact: () => true,
|
|
78376
|
+
// Codex maps '/compact' to thread/compact/start
|
|
78377
|
+
tries: () => overflowTries.get(threadId) ?? 0,
|
|
78378
|
+
bump: () => overflowTries.set(threadId, (overflowTries.get(threadId) ?? 0) + 1),
|
|
78379
|
+
context: { sessionId: threadId, engine: "codex" },
|
|
78380
|
+
compactAndResume: async () => {
|
|
78381
|
+
await sendMessage({ ...params, message: OVERFLOW_COMPACT_MESSAGE, sessionId: threadId, autoContinuation: true });
|
|
78382
|
+
await sendMessage({ ...params, message: OVERFLOW_RESUME_MESSAGE, sessionId: threadId, autoContinuation: true });
|
|
78383
|
+
}
|
|
78384
|
+
});
|
|
78385
|
+
if (recovered)
|
|
78386
|
+
return;
|
|
77797
78387
|
send4({ type: "chat:error", sessionId: threadId, clientRequestId: params.clientRequestId, error: detail, continuable: true, continueReason: "context_window" }, origin);
|
|
77798
78388
|
send4({ type: "agent:status", sessionId: threadId, clientRequestId: params.clientRequestId, status: "idle" }, origin);
|
|
77799
78389
|
return;
|
|
@@ -78445,7 +79035,7 @@ async function createBackend(engineId, send4, onBrowserRequest, resolver, loadPl
|
|
|
78445
79035
|
// ../../packages/host-core/dist/session-recorder.js
|
|
78446
79036
|
init_base_paths();
|
|
78447
79037
|
import { join as join27 } from "node:path";
|
|
78448
|
-
import { mkdirSync as
|
|
79038
|
+
import { mkdirSync as mkdirSync16, writeFileSync as writeFileSync17, appendFileSync as appendFileSync3, readdirSync as readdirSync4, rmSync as rmSync2, statSync as statSync8 } from "node:fs";
|
|
78449
79039
|
init_dist5();
|
|
78450
79040
|
var dir = null;
|
|
78451
79041
|
var seq = 0;
|
|
@@ -78470,7 +79060,7 @@ function recordEvent(type, data = {}) {
|
|
|
78470
79060
|
if (!dir)
|
|
78471
79061
|
return;
|
|
78472
79062
|
try {
|
|
78473
|
-
|
|
79063
|
+
appendFileSync3(join27(dir, "events.jsonl"), `${JSON.stringify({ ts: now(), seq: seq++, type, ...data })}
|
|
78474
79064
|
`);
|
|
78475
79065
|
} catch {
|
|
78476
79066
|
}
|
|
@@ -78481,8 +79071,8 @@ init_dist5();
|
|
|
78481
79071
|
|
|
78482
79072
|
// ../../packages/host-core/dist/plugin-tools.js
|
|
78483
79073
|
init_base_paths();
|
|
78484
|
-
import { existsSync as
|
|
78485
|
-
import { join as join28, dirname as
|
|
79074
|
+
import { existsSync as existsSync12, readdirSync as readdirSync5 } from "node:fs";
|
|
79075
|
+
import { join as join28, dirname as dirname11 } from "node:path";
|
|
78486
79076
|
|
|
78487
79077
|
// ../../packages/plugin-host/dist/index.js
|
|
78488
79078
|
init_dist();
|
|
@@ -78816,7 +79406,7 @@ function convertTool(t) {
|
|
|
78816
79406
|
};
|
|
78817
79407
|
}
|
|
78818
79408
|
function createOpenClawAdapter(pluginId, config2, secretResolver, registry3) {
|
|
78819
|
-
const
|
|
79409
|
+
const warned2 = /* @__PURE__ */ new Set();
|
|
78820
79410
|
const impl = {
|
|
78821
79411
|
pluginId,
|
|
78822
79412
|
config: config2,
|
|
@@ -78887,8 +79477,8 @@ function createOpenClawAdapter(pluginId, config2, secretResolver, registry3) {
|
|
|
78887
79477
|
return Reflect.get(target, prop, recv);
|
|
78888
79478
|
if (typeof prop === "string") {
|
|
78889
79479
|
return (..._args) => {
|
|
78890
|
-
if (!
|
|
78891
|
-
|
|
79480
|
+
if (!warned2.has(prop)) {
|
|
79481
|
+
warned2.add(prop);
|
|
78892
79482
|
registry3.diagnostics.push(`[${pluginId}] api.${prop}() is not supported by the Tesseract host \u2014 ignored`);
|
|
78893
79483
|
}
|
|
78894
79484
|
};
|
|
@@ -79000,7 +79590,7 @@ function buildDaemonPluginLoader(pluginsDir) {
|
|
|
79000
79590
|
return async () => {
|
|
79001
79591
|
const skillsPlugin = daemonSkillsPluginConfig();
|
|
79002
79592
|
const snap = readDaemonAgentSettings();
|
|
79003
|
-
const desktopRoots = (snap.pluginRoots ?? []).filter((r) => r?.dir &&
|
|
79593
|
+
const desktopRoots = (snap.pluginRoots ?? []).filter((r) => r?.dir && existsSync12(r.dir));
|
|
79004
79594
|
if (desktopRoots.length > 0) {
|
|
79005
79595
|
const resDir = process.resourcesPath;
|
|
79006
79596
|
for (const r of desktopRoots) {
|
|
@@ -79009,7 +79599,7 @@ function buildDaemonPluginLoader(pluginsDir) {
|
|
|
79009
79599
|
if (resDir && r.dir.startsWith(resDir))
|
|
79010
79600
|
continue;
|
|
79011
79601
|
try {
|
|
79012
|
-
writeOpenClawShim(r.dir.endsWith("node_modules") ?
|
|
79602
|
+
writeOpenClawShim(r.dir.endsWith("node_modules") ? dirname11(r.dir) : r.dir);
|
|
79013
79603
|
} catch {
|
|
79014
79604
|
}
|
|
79015
79605
|
}
|
|
@@ -79023,7 +79613,7 @@ function buildDaemonPluginLoader(pluginsDir) {
|
|
|
79023
79613
|
return { ...rt2, skillsPlugin };
|
|
79024
79614
|
}
|
|
79025
79615
|
const scan = join28(pluginsDir, "node_modules");
|
|
79026
|
-
if (!
|
|
79616
|
+
if (!existsSync12(scan))
|
|
79027
79617
|
return { tools: [], hooks: [], messageHooks: [], commands: [], themeOps: [], engines: [], skillsPlugin };
|
|
79028
79618
|
writeOpenClawShim(pluginsDir);
|
|
79029
79619
|
const rt = await loadPluginRuntime({
|
|
@@ -79035,11 +79625,11 @@ function buildDaemonPluginLoader(pluginsDir) {
|
|
|
79035
79625
|
}
|
|
79036
79626
|
function daemonSkillsPluginConfig() {
|
|
79037
79627
|
const root = readDaemonAgentSettings().skillsRoot ?? tessPath("extensions-skills");
|
|
79038
|
-
if (!
|
|
79628
|
+
if (!existsSync12(join28(root, ".claude-plugin", "plugin.json")))
|
|
79039
79629
|
return null;
|
|
79040
79630
|
const enabled = join28(root, "skills");
|
|
79041
79631
|
try {
|
|
79042
|
-
const hasSkill = readdirSync5(enabled).some((slug2) =>
|
|
79632
|
+
const hasSkill = readdirSync5(enabled).some((slug2) => existsSync12(join28(enabled, slug2, "SKILL.md")));
|
|
79043
79633
|
return hasSkill ? { type: "local", path: root } : null;
|
|
79044
79634
|
} catch {
|
|
79045
79635
|
return null;
|
|
@@ -79241,10 +79831,10 @@ async function enableEditorMirror(browserId, onEvent) {
|
|
|
79241
79831
|
});
|
|
79242
79832
|
page.on("pageerror", (err2) => relay({ level: "error", kind: "console", message: err2.message }));
|
|
79243
79833
|
page.on("requestfailed", (req) => {
|
|
79244
|
-
const
|
|
79245
|
-
if (
|
|
79834
|
+
const errText2 = req.failure()?.errorText ?? "request failed";
|
|
79835
|
+
if (errText2.includes("ERR_ABORTED"))
|
|
79246
79836
|
return;
|
|
79247
|
-
relay({ level: "error", kind: "network", message: `Failed to load ${req.url()} \u2014 ${
|
|
79837
|
+
relay({ level: "error", kind: "network", message: `Failed to load ${req.url()} \u2014 ${errText2}` });
|
|
79248
79838
|
});
|
|
79249
79839
|
page.on("close", () => editorErrorTaps.delete(browserId));
|
|
79250
79840
|
}
|
|
@@ -79339,10 +79929,10 @@ import { join as join30 } from "node:path";
|
|
|
79339
79929
|
|
|
79340
79930
|
// ../../packages/host-core/dist/gui/daemon-gui.js
|
|
79341
79931
|
init_credentials();
|
|
79342
|
-
import { join as join29, dirname as
|
|
79932
|
+
import { join as join29, dirname as dirname12 } from "node:path";
|
|
79343
79933
|
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
79344
79934
|
import { spawn as spawn9, spawnSync } from "node:child_process";
|
|
79345
|
-
import { existsSync as
|
|
79935
|
+
import { existsSync as existsSync13 } from "node:fs";
|
|
79346
79936
|
|
|
79347
79937
|
// ../../packages/host-core/dist/gui/main-app-launch.js
|
|
79348
79938
|
var LAUNCH_MARKERS = [
|
|
@@ -79578,14 +80168,14 @@ function daemonUiDir() {
|
|
|
79578
80168
|
return resolvedUiDir;
|
|
79579
80169
|
const ok = (d) => {
|
|
79580
80170
|
try {
|
|
79581
|
-
return
|
|
80171
|
+
return existsSync13(join29(d, "preload.cjs"));
|
|
79582
80172
|
} catch {
|
|
79583
80173
|
return false;
|
|
79584
80174
|
}
|
|
79585
80175
|
};
|
|
79586
80176
|
let here = null;
|
|
79587
80177
|
try {
|
|
79588
|
-
here =
|
|
80178
|
+
here = dirname12(fileURLToPath4(import.meta.url));
|
|
79589
80179
|
} catch {
|
|
79590
80180
|
here = null;
|
|
79591
80181
|
}
|
|
@@ -79617,8 +80207,8 @@ function devAppPath() {
|
|
|
79617
80207
|
return env;
|
|
79618
80208
|
const daemonEntry = process.argv[1];
|
|
79619
80209
|
if (daemonEntry) {
|
|
79620
|
-
const cand = join29(
|
|
79621
|
-
if (
|
|
80210
|
+
const cand = join29(dirname12(daemonEntry), "..", "..", "desktop");
|
|
80211
|
+
if (existsSync13(join29(cand, "package.json")))
|
|
79622
80212
|
return cand;
|
|
79623
80213
|
}
|
|
79624
80214
|
return null;
|
|
@@ -80001,7 +80591,7 @@ function widgetDisplayBounds(w) {
|
|
|
80001
80591
|
}
|
|
80002
80592
|
|
|
80003
80593
|
// ../../packages/host-core/dist/gui/ai-control.js
|
|
80004
|
-
import { join as join31, dirname as
|
|
80594
|
+
import { join as join31, dirname as dirname13 } from "node:path";
|
|
80005
80595
|
import { randomUUID as randomUUID14 } from "node:crypto";
|
|
80006
80596
|
init_dist5();
|
|
80007
80597
|
init_credentials();
|
|
@@ -80081,7 +80671,7 @@ var MOONDREAM_URL = (process.env.CCB_MOONDREAM_URL?.trim() || "http://127.0.0.1:
|
|
|
80081
80671
|
|
|
80082
80672
|
// ../../packages/host-core/dist/voice-control.js
|
|
80083
80673
|
init_base_paths();
|
|
80084
|
-
import { existsSync as
|
|
80674
|
+
import { existsSync as existsSync14, readFileSync as readFileSync23 } from "node:fs";
|
|
80085
80675
|
import { basename as basename4, join as join32 } from "node:path";
|
|
80086
80676
|
|
|
80087
80677
|
// ../../packages/voice-core/dist/providers/tool-adapters.js
|
|
@@ -81332,8 +81922,8 @@ function readGeminiKeyFile() {
|
|
|
81332
81922
|
try {
|
|
81333
81923
|
const home = tesseractHome();
|
|
81334
81924
|
const f = join32(home, "daemon", "gemini.key");
|
|
81335
|
-
if (
|
|
81336
|
-
const k =
|
|
81925
|
+
if (existsSync14(f)) {
|
|
81926
|
+
const k = readFileSync23(f, "utf-8").trim();
|
|
81337
81927
|
if (k)
|
|
81338
81928
|
return k;
|
|
81339
81929
|
}
|
|
@@ -81751,13 +82341,13 @@ ${priorText}` : "";
|
|
|
81751
82341
|
};
|
|
81752
82342
|
|
|
81753
82343
|
// ../../packages/host-core/dist/daemon-agent.js
|
|
81754
|
-
import { mkdirSync as
|
|
82344
|
+
import { mkdirSync as mkdirSync22 } from "node:fs";
|
|
81755
82345
|
init_pool();
|
|
81756
82346
|
|
|
81757
82347
|
// ../../packages/host-core/dist/image-gen-runner.js
|
|
81758
82348
|
init_base_paths();
|
|
81759
82349
|
import { randomUUID as randomUUID16 } from "node:crypto";
|
|
81760
|
-
import { mkdirSync as
|
|
82350
|
+
import { mkdirSync as mkdirSync17, writeFileSync as writeFileSync18, readFileSync as readFileSync24 } from "node:fs";
|
|
81761
82351
|
import { join as join33 } from "node:path";
|
|
81762
82352
|
|
|
81763
82353
|
// ../../packages/image-edit-core/dist/transparent.js
|
|
@@ -82246,7 +82836,7 @@ function createDaemonImageGenRunner() {
|
|
|
82246
82836
|
let inputMime;
|
|
82247
82837
|
if (req.sourceImagePath) {
|
|
82248
82838
|
try {
|
|
82249
|
-
inputImageB64 =
|
|
82839
|
+
inputImageB64 = readFileSync24(req.sourceImagePath).toString("base64");
|
|
82250
82840
|
const lower = req.sourceImagePath.toLowerCase();
|
|
82251
82841
|
inputMime = lower.endsWith(".jpg") || lower.endsWith(".jpeg") ? "image/jpeg" : lower.endsWith(".webp") ? "image/webp" : "image/png";
|
|
82252
82842
|
} catch (e) {
|
|
@@ -82267,7 +82857,7 @@ function createDaemonImageGenRunner() {
|
|
|
82267
82857
|
if (!images.length)
|
|
82268
82858
|
return { ok: false, error: "The provider returned no image." };
|
|
82269
82859
|
const dir2 = req.outDir ?? join33(generatedImagesDir(), randomUUID16());
|
|
82270
|
-
|
|
82860
|
+
mkdirSync17(dir2, { recursive: true });
|
|
82271
82861
|
const files = images.map((img, i) => {
|
|
82272
82862
|
const ext = img.mime.split("/")[1]?.split("+")[0] || "png";
|
|
82273
82863
|
const path6 = join33(dir2, `${i + 1}.${ext}`);
|
|
@@ -82287,7 +82877,7 @@ function createDaemonImageGenRunner() {
|
|
|
82287
82877
|
init_serpapi_runner();
|
|
82288
82878
|
|
|
82289
82879
|
// ../../packages/host-core/dist/video-gen-runner.js
|
|
82290
|
-
import { readFileSync as
|
|
82880
|
+
import { readFileSync as readFileSync26 } from "node:fs";
|
|
82291
82881
|
|
|
82292
82882
|
// ../../packages/video-core/dist/cost.js
|
|
82293
82883
|
var VEO_RATES = [
|
|
@@ -83687,9 +84277,9 @@ init_daemon_settings();
|
|
|
83687
84277
|
|
|
83688
84278
|
// ../../packages/host-core/dist/video-jobs.js
|
|
83689
84279
|
init_base_paths();
|
|
83690
|
-
import { mkdirSync as
|
|
84280
|
+
import { mkdirSync as mkdirSync18, readdirSync as readdirSync6, readFileSync as readFileSync25, writeFileSync as writeFileSync19, rmSync as rmSync3 } from "node:fs";
|
|
83691
84281
|
import { mkdir as mkdir6, writeFile as writeFile7 } from "node:fs/promises";
|
|
83692
|
-
import { dirname as
|
|
84282
|
+
import { dirname as dirname14, join as join34 } from "node:path";
|
|
83693
84283
|
import { randomUUID as randomUUID17 } from "node:crypto";
|
|
83694
84284
|
function mediaJobsDir() {
|
|
83695
84285
|
const home = tesseractHome();
|
|
@@ -83738,7 +84328,7 @@ var VideoJobRegistry = class {
|
|
|
83738
84328
|
if (mem)
|
|
83739
84329
|
return { ...mem };
|
|
83740
84330
|
try {
|
|
83741
|
-
const raw =
|
|
84331
|
+
const raw = readFileSync25(join34(mediaJobsDir(), `${jobId}.json`), "utf-8");
|
|
83742
84332
|
return JSON.parse(raw);
|
|
83743
84333
|
} catch {
|
|
83744
84334
|
return null;
|
|
@@ -83790,7 +84380,7 @@ var VideoJobRegistry = class {
|
|
|
83790
84380
|
for (const f of files) {
|
|
83791
84381
|
const fp = join34(mediaJobsDir(), f);
|
|
83792
84382
|
try {
|
|
83793
|
-
const job = JSON.parse(
|
|
84383
|
+
const job = JSON.parse(readFileSync25(fp, "utf-8"));
|
|
83794
84384
|
if (TERMINAL.has(job.state)) {
|
|
83795
84385
|
if (now2 - (job.updatedAt ?? job.createdAt ?? now2) > DISK_RETENTION_MS)
|
|
83796
84386
|
rmSync3(fp, { force: true });
|
|
@@ -83874,7 +84464,7 @@ var VideoJobRegistry = class {
|
|
|
83874
84464
|
this.materializing.add(job.id);
|
|
83875
84465
|
try {
|
|
83876
84466
|
const res = await provider.fetchResult({ providerId: job.providerId, model: job.model, operationName: job.operationName });
|
|
83877
|
-
await mkdir6(
|
|
84467
|
+
await mkdir6(dirname14(job.outPath), { recursive: true });
|
|
83878
84468
|
await writeFile7(job.outPath, res.bytes);
|
|
83879
84469
|
this.update(job, { state: "succeeded", mime: res.mime, progressPct: 100 });
|
|
83880
84470
|
} catch (e) {
|
|
@@ -83910,7 +84500,7 @@ var VideoJobRegistry = class {
|
|
|
83910
84500
|
persist(job) {
|
|
83911
84501
|
this.jobs.set(job.id, job);
|
|
83912
84502
|
try {
|
|
83913
|
-
|
|
84503
|
+
mkdirSync18(mediaJobsDir(), { recursive: true });
|
|
83914
84504
|
writeFileSync19(join34(mediaJobsDir(), `${job.id}.json`), JSON.stringify(job, null, 2));
|
|
83915
84505
|
} catch {
|
|
83916
84506
|
}
|
|
@@ -83955,7 +84545,7 @@ function buildProvider(id, pc, model) {
|
|
|
83955
84545
|
function readFrame(path6) {
|
|
83956
84546
|
const lower = path6.toLowerCase();
|
|
83957
84547
|
const mime = lower.endsWith(".jpg") || lower.endsWith(".jpeg") ? "image/jpeg" : lower.endsWith(".webp") ? "image/webp" : "image/png";
|
|
83958
|
-
return { bytes: new Uint8Array(
|
|
84548
|
+
return { bytes: new Uint8Array(readFileSync26(path6)), mime };
|
|
83959
84549
|
}
|
|
83960
84550
|
function providerForJob(providerId, model) {
|
|
83961
84551
|
const c = creds2();
|
|
@@ -84063,7 +84653,7 @@ function createDaemonVideoGenRunner() {
|
|
|
84063
84653
|
|
|
84064
84654
|
// ../../packages/host-core/dist/video-edit-runner.js
|
|
84065
84655
|
init_base_paths();
|
|
84066
|
-
import { existsSync as
|
|
84656
|
+
import { existsSync as existsSync17, readFileSync as readFileSync31 } from "node:fs";
|
|
84067
84657
|
import { mkdir as mkdir7, writeFile as writeFile8 } from "node:fs/promises";
|
|
84068
84658
|
import { join as join38, basename as basename6 } from "node:path";
|
|
84069
84659
|
import { randomUUID as randomUUID19 } from "node:crypto";
|
|
@@ -84072,12 +84662,12 @@ init_daemon_settings();
|
|
|
84072
84662
|
// ../../packages/host-core/dist/video-edit.js
|
|
84073
84663
|
init_base_paths();
|
|
84074
84664
|
import { spawn as spawn11 } from "node:child_process";
|
|
84075
|
-
import { mkdirSync as
|
|
84665
|
+
import { mkdirSync as mkdirSync19, readFileSync as readFileSync27, rmSync as rmSync4, writeFileSync as writeFileSync20 } from "node:fs";
|
|
84076
84666
|
import { join as join35, isAbsolute as isAbsolute5 } from "node:path";
|
|
84077
84667
|
import { randomUUID as randomUUID18 } from "node:crypto";
|
|
84078
84668
|
|
|
84079
84669
|
// ../../packages/host-core/dist/ffmpeg.js
|
|
84080
|
-
import { existsSync as
|
|
84670
|
+
import { existsSync as existsSync15 } from "node:fs";
|
|
84081
84671
|
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
84082
84672
|
import { sep as sep5 } from "node:path";
|
|
84083
84673
|
import { createRequire as createRequire3 } from "node:module";
|
|
@@ -84090,7 +84680,7 @@ function fromPackage(name) {
|
|
|
84090
84680
|
if (typeof raw !== "string")
|
|
84091
84681
|
return null;
|
|
84092
84682
|
const p = unpacked(raw);
|
|
84093
|
-
return
|
|
84683
|
+
return existsSync15(p) ? p : null;
|
|
84094
84684
|
} catch {
|
|
84095
84685
|
return null;
|
|
84096
84686
|
}
|
|
@@ -84106,7 +84696,7 @@ function fromPath(cmd) {
|
|
|
84106
84696
|
function resolveBinary(envVar, pkg, cmd, hint) {
|
|
84107
84697
|
const env = process.env[envVar]?.trim();
|
|
84108
84698
|
if (env) {
|
|
84109
|
-
if (
|
|
84699
|
+
if (existsSync15(env) || fromPath(env))
|
|
84110
84700
|
return env;
|
|
84111
84701
|
throw new Error(`${envVar}=${env} does not exist or is not executable.`);
|
|
84112
84702
|
}
|
|
@@ -84148,14 +84738,14 @@ var mediaCwd;
|
|
|
84148
84738
|
function mediaSpawnCwd() {
|
|
84149
84739
|
if (!mediaCwd) {
|
|
84150
84740
|
mediaCwd = tessPath("media-work");
|
|
84151
|
-
|
|
84741
|
+
mkdirSync19(mediaCwd, { recursive: true });
|
|
84152
84742
|
}
|
|
84153
84743
|
return mediaCwd;
|
|
84154
84744
|
}
|
|
84155
84745
|
var workDir = () => {
|
|
84156
84746
|
const home = tesseractHome();
|
|
84157
84747
|
const dir2 = join35(home, "media-work", randomUUID18());
|
|
84158
|
-
|
|
84748
|
+
mkdirSync19(dir2, { recursive: true });
|
|
84159
84749
|
return dir2;
|
|
84160
84750
|
};
|
|
84161
84751
|
var MIME_BY_EXT = {
|
|
@@ -84244,7 +84834,7 @@ async function renderEdl(edl, opts) {
|
|
|
84244
84834
|
}
|
|
84245
84835
|
}
|
|
84246
84836
|
const dir2 = opts.outDir ?? workDir();
|
|
84247
|
-
|
|
84837
|
+
mkdirSync19(dir2, { recursive: true });
|
|
84248
84838
|
const format = edl.output?.format ?? "mp4";
|
|
84249
84839
|
const outPath = join35(dir2, `edit.${format}`);
|
|
84250
84840
|
let assFile;
|
|
@@ -84318,7 +84908,7 @@ async function enhanceVideo(path6, spec, opts) {
|
|
|
84318
84908
|
throw new Error("Nothing to enhance \u2014 request at least one of: upscale, denoise, deblock, deband, sharpen, or interpolate.");
|
|
84319
84909
|
}
|
|
84320
84910
|
const dir2 = opts?.outDir ?? workDir();
|
|
84321
|
-
|
|
84911
|
+
mkdirSync19(dir2, { recursive: true });
|
|
84322
84912
|
const outPath = join35(dir2, "enhanced.mp4");
|
|
84323
84913
|
const audioArgs = probe.hasAudio ? ["-c:a", "copy"] : ["-an"];
|
|
84324
84914
|
const args = [
|
|
@@ -84396,7 +84986,7 @@ ${stderrTail}`));
|
|
|
84396
84986
|
async function extractFrames(path6, timestamps, outDir) {
|
|
84397
84987
|
path6 = requireAbsolutePath(path6, "path");
|
|
84398
84988
|
const dir2 = outDir ?? workDir();
|
|
84399
|
-
|
|
84989
|
+
mkdirSync19(dir2, { recursive: true });
|
|
84400
84990
|
const out = [];
|
|
84401
84991
|
for (const [i, ts] of timestamps.slice(0, 20).entries()) {
|
|
84402
84992
|
const file2 = join35(dir2, `frame-${i + 1}-${Math.round(ts * 1e3)}ms.jpg`);
|
|
@@ -84431,7 +85021,7 @@ async function detectSilence(path6, opts) {
|
|
|
84431
85021
|
async function extractAudio(path6, format, outDir, opts) {
|
|
84432
85022
|
path6 = requireAbsolutePath(path6, "path");
|
|
84433
85023
|
const dir2 = outDir ?? workDir();
|
|
84434
|
-
|
|
85024
|
+
mkdirSync19(dir2, { recursive: true });
|
|
84435
85025
|
const out = join35(dir2, `audio.${format}`);
|
|
84436
85026
|
const codec2 = format === "mp3" ? ["-c:a", "libmp3lame", "-q:a", "2"] : format === "wav" ? ["-c:a", "pcm_s16le"] : ["-c:a", "aac", "-b:a", "192k"];
|
|
84437
85027
|
const gain = opts?.gainDb ? ["-af", `volume=${opts.gainDb}dB`] : [];
|
|
@@ -84447,7 +85037,7 @@ async function isolateSpeakerAudio(path6, windows2, outDir) {
|
|
|
84447
85037
|
const merged = mergeWindows(windows2).slice(0, 200);
|
|
84448
85038
|
const enable = merged.map((w) => `between(t,${w.startSec},${w.endSec})`).join("+");
|
|
84449
85039
|
const dir2 = outDir ?? workDir();
|
|
84450
|
-
|
|
85040
|
+
mkdirSync19(dir2, { recursive: true });
|
|
84451
85041
|
const out = join35(dir2, "speaker.m4a");
|
|
84452
85042
|
const r = await run2(resolveFfmpeg(), ["-y", "-i", path6, "-vn", "-af", `volume=enable='1-min(1,${enable})':volume=0`, "-c:a", "aac", "-b:a", "192k", out], {
|
|
84453
85043
|
timeoutMs: LONG_TIMEOUT_MS
|
|
@@ -84501,19 +85091,19 @@ function cleanupDir(dir2) {
|
|
|
84501
85091
|
}
|
|
84502
85092
|
}
|
|
84503
85093
|
function readChunkBase64(path6) {
|
|
84504
|
-
return
|
|
85094
|
+
return readFileSync27(path6).toString("base64");
|
|
84505
85095
|
}
|
|
84506
85096
|
|
|
84507
85097
|
// ../../packages/host-core/dist/video-upscale.js
|
|
84508
85098
|
init_base_paths();
|
|
84509
85099
|
import { spawn as spawn12 } from "node:child_process";
|
|
84510
|
-
import { existsSync as
|
|
84511
|
-
import { join as join36, dirname as
|
|
85100
|
+
import { existsSync as existsSync16, mkdirSync as mkdirSync20, readFileSync as readFileSync28, readdirSync as readdirSync7 } from "node:fs";
|
|
85101
|
+
import { join as join36, dirname as dirname15 } from "node:path";
|
|
84512
85102
|
var upscaleCwd;
|
|
84513
85103
|
function upscaleSpawnCwd() {
|
|
84514
85104
|
if (!upscaleCwd) {
|
|
84515
85105
|
upscaleCwd = tessPath("media-work");
|
|
84516
|
-
|
|
85106
|
+
mkdirSync20(upscaleCwd, { recursive: true });
|
|
84517
85107
|
}
|
|
84518
85108
|
return upscaleCwd;
|
|
84519
85109
|
}
|
|
@@ -84525,12 +85115,12 @@ function resolveRealesrgan() {
|
|
|
84525
85115
|
envBin,
|
|
84526
85116
|
// Packaged app: extraResources → Resources/vendor/realesrgan/<plat>/…
|
|
84527
85117
|
process.resourcesPath ? join36(process.resourcesPath, "vendor", "realesrgan", platDir, exe) : void 0
|
|
84528
|
-
].filter((p) => !!p &&
|
|
85118
|
+
].filter((p) => !!p && existsSync16(p));
|
|
84529
85119
|
const bin = candidates[0] ?? fromPath2("realesrgan-ncnn-vulkan");
|
|
84530
85120
|
if (!bin)
|
|
84531
85121
|
return null;
|
|
84532
|
-
const models = process.env.TESSERACT_REALESRGAN_MODELS?.trim() || join36(
|
|
84533
|
-
return
|
|
85122
|
+
const models = process.env.TESSERACT_REALESRGAN_MODELS?.trim() || join36(dirname15(bin), "models");
|
|
85123
|
+
return existsSync16(models) ? { bin, models } : null;
|
|
84534
85124
|
}
|
|
84535
85125
|
function fromPath2(cmd) {
|
|
84536
85126
|
try {
|
|
@@ -84552,8 +85142,8 @@ function installedRealesrModels() {
|
|
|
84552
85142
|
return [];
|
|
84553
85143
|
return REALESRGAN_MODELS.filter((m) => {
|
|
84554
85144
|
if (m.scales.length > 1)
|
|
84555
|
-
return m.scales.some((s) =>
|
|
84556
|
-
return
|
|
85145
|
+
return m.scales.some((s) => existsSync16(join36(re.models, `${m.id}-x${s}.bin`)));
|
|
85146
|
+
return existsSync16(join36(re.models, `${m.id}.bin`));
|
|
84557
85147
|
}).map((m) => m.id);
|
|
84558
85148
|
}
|
|
84559
85149
|
function upscaleAdvert() {
|
|
@@ -84574,7 +85164,7 @@ async function realesrganGpuWorks() {
|
|
|
84574
85164
|
const dir2 = workDir();
|
|
84575
85165
|
const inP = join36(dir2, "p.png"), outP = join36(dir2, "p2.png");
|
|
84576
85166
|
const gen = await run2(resolveFfmpeg(), ["-y", "-f", "lavfi", "-i", "testsrc=size=64x64:duration=1", "-frames:v", "1", inP], { timeoutMs: 15e3 });
|
|
84577
|
-
if (!gen.ok || !
|
|
85167
|
+
if (!gen.ok || !existsSync16(inP)) {
|
|
84578
85168
|
gpuProbe = false;
|
|
84579
85169
|
return false;
|
|
84580
85170
|
}
|
|
@@ -84593,7 +85183,7 @@ async function realesrganGpuWorks() {
|
|
|
84593
85183
|
code === 0 ? resolve16() : reject(new Error(`exit ${code}`));
|
|
84594
85184
|
});
|
|
84595
85185
|
});
|
|
84596
|
-
gpuProbe =
|
|
85186
|
+
gpuProbe = existsSync16(outP);
|
|
84597
85187
|
} catch {
|
|
84598
85188
|
gpuProbe = false;
|
|
84599
85189
|
}
|
|
@@ -84612,8 +85202,8 @@ async function upscaleCapabilities(opts) {
|
|
|
84612
85202
|
function resolveFalKey() {
|
|
84613
85203
|
const home = tesseractHome();
|
|
84614
85204
|
const file2 = join36(home, "daemon", "fal.key");
|
|
84615
|
-
if (
|
|
84616
|
-
const k =
|
|
85205
|
+
if (existsSync16(file2)) {
|
|
85206
|
+
const k = readFileSync28(file2, "utf-8").trim();
|
|
84617
85207
|
if (k)
|
|
84618
85208
|
return k;
|
|
84619
85209
|
}
|
|
@@ -84660,8 +85250,8 @@ async function realesrganUpscale(path6, opts) {
|
|
|
84660
85250
|
const scale = opts.scale ?? 2;
|
|
84661
85251
|
const dir2 = opts.outDir ?? workDir();
|
|
84662
85252
|
const fin = join36(dir2, "in"), fup = join36(dir2, "up");
|
|
84663
|
-
|
|
84664
|
-
|
|
85253
|
+
mkdirSync20(fin, { recursive: true });
|
|
85254
|
+
mkdirSync20(fup, { recursive: true });
|
|
84665
85255
|
const fps = p.fps ?? 30;
|
|
84666
85256
|
const src = path6;
|
|
84667
85257
|
let extractSrc = src;
|
|
@@ -84728,7 +85318,7 @@ async function falTopazEnhance(path6, spec, opts) {
|
|
|
84728
85318
|
path6 = requireAbsolutePath(path6, "path");
|
|
84729
85319
|
const p = await probeMedia(path6);
|
|
84730
85320
|
opts.onProgress?.(3, "Uploading to fal\u2026");
|
|
84731
|
-
const bytes2 =
|
|
85321
|
+
const bytes2 = readFileSync28(path6);
|
|
84732
85322
|
const videoUrl = await falUploadVideo(new Uint8Array(bytes2), "video/mp4", { apiKey: opts.apiKey });
|
|
84733
85323
|
opts.onProgress?.(12, "Submitting Topaz job\u2026");
|
|
84734
85324
|
const sub = await falTopazSubmit({ ...spec, videoUrl }, { apiKey: opts.apiKey });
|
|
@@ -84755,7 +85345,7 @@ async function falTopazEnhance(path6, spec, opts) {
|
|
|
84755
85345
|
if (!dl.ok)
|
|
84756
85346
|
throw new Error(`Downloading the fal result failed (HTTP ${dl.status}).`);
|
|
84757
85347
|
const dir2 = opts.outDir ?? workDir();
|
|
84758
|
-
|
|
85348
|
+
mkdirSync20(dir2, { recursive: true });
|
|
84759
85349
|
const outPath = join36(dir2, "enhanced.mp4");
|
|
84760
85350
|
const { writeFileSync: writeFileSync43 } = await import("node:fs");
|
|
84761
85351
|
writeFileSync43(outPath, Buffer.from(await dl.arrayBuffer()));
|
|
@@ -84801,7 +85391,7 @@ async function smartEnhance(path6, args) {
|
|
|
84801
85391
|
}
|
|
84802
85392
|
|
|
84803
85393
|
// ../../packages/host-core/dist/video-effects.js
|
|
84804
|
-
import { readFileSync as
|
|
85394
|
+
import { readFileSync as readFileSync29, mkdirSync as mkdirSync21, writeFileSync as writeFileSync21 } from "node:fs";
|
|
84805
85395
|
import { join as join37, basename as basename5, extname } from "node:path";
|
|
84806
85396
|
init_daemon_settings();
|
|
84807
85397
|
var IMG_MIME = { jpg: "image/jpeg", jpeg: "image/jpeg", png: "image/png", webp: "image/webp", heic: "image/heic" };
|
|
@@ -84840,11 +85430,11 @@ async function applyEffect(effectId, inputs, opts) {
|
|
|
84840
85430
|
const imageUrls = [];
|
|
84841
85431
|
for (const p of imgs.slice(0, needImgs || imgs.length)) {
|
|
84842
85432
|
const ext2 = extname(p).slice(1).toLowerCase();
|
|
84843
|
-
imageUrls.push(await falUploadVideo(new Uint8Array(
|
|
85433
|
+
imageUrls.push(await falUploadVideo(new Uint8Array(readFileSync29(p)), IMG_MIME[ext2] ?? "image/jpeg", { apiKey: key2, fileName: basename5(p) }));
|
|
84844
85434
|
}
|
|
84845
85435
|
let videoUrl;
|
|
84846
85436
|
if (inputs.videoPath)
|
|
84847
|
-
videoUrl = await falUploadVideo(new Uint8Array(
|
|
85437
|
+
videoUrl = await falUploadVideo(new Uint8Array(readFileSync29(inputs.videoPath)), "video/mp4", { apiKey: key2, fileName: basename5(inputs.videoPath) });
|
|
84848
85438
|
const body = { ...def.params };
|
|
84849
85439
|
const usesImageArray = def.modelPath.includes("/vidu/") || def.modelPath.includes("/kling-video/") || def.modelPath.includes("nano-banana");
|
|
84850
85440
|
const arrayKey = def.modelPath.includes("nano-banana") ? "image_urls" : "input_image_urls";
|
|
@@ -84888,7 +85478,7 @@ async function applyEffect(effectId, inputs, opts) {
|
|
|
84888
85478
|
if (!dl.ok)
|
|
84889
85479
|
throw new Error(`Downloading the result failed (HTTP ${dl.status}).`);
|
|
84890
85480
|
const dir2 = opts?.outDir ?? workDir();
|
|
84891
|
-
|
|
85481
|
+
mkdirSync21(dir2, { recursive: true });
|
|
84892
85482
|
const ext = media.isVideo ? "mp4" : extname(new URL(media.url).pathname).slice(1) || "png";
|
|
84893
85483
|
const outPath = join37(dir2, `${effectId}.${ext}`);
|
|
84894
85484
|
writeFileSync21(outPath, Buffer.from(await dl.arrayBuffer()));
|
|
@@ -84913,9 +85503,9 @@ async function applyGeminiImageEffect(def, inputs, opts) {
|
|
|
84913
85503
|
${inputs.prompt}` : "");
|
|
84914
85504
|
opts?.onProgress?.(10, `Generating ${def.label}\u2026`);
|
|
84915
85505
|
const provider = createImageEditProvider("google", { apiKey: key2, model: def.modelPath });
|
|
84916
|
-
const out = await runImageEdit(provider, { op: "prompt", imageB64:
|
|
85506
|
+
const out = await runImageEdit(provider, { op: "prompt", imageB64: readFileSync29(imgPath).toString("base64"), mime: IMG_MIME[ext] ?? "image/jpeg", prompt });
|
|
84917
85507
|
const dir2 = opts?.outDir ?? workDir();
|
|
84918
|
-
|
|
85508
|
+
mkdirSync21(dir2, { recursive: true });
|
|
84919
85509
|
const outPath = join37(dir2, `${def.id}.png`);
|
|
84920
85510
|
writeFileSync21(outPath, Buffer.from(out.bytes));
|
|
84921
85511
|
opts?.onProgress?.(100, "Done");
|
|
@@ -85035,13 +85625,13 @@ ${compact2}`;
|
|
|
85035
85625
|
}
|
|
85036
85626
|
|
|
85037
85627
|
// ../../packages/host-core/dist/video-vision.js
|
|
85038
|
-
import { readFileSync as
|
|
85628
|
+
import { readFileSync as readFileSync30 } from "node:fs";
|
|
85039
85629
|
var BASE_URL3 = "https://generativelanguage.googleapis.com/v1beta";
|
|
85040
85630
|
var MODEL = "gemini-3.5-flash";
|
|
85041
85631
|
var TIMEOUT_MS = 6e4;
|
|
85042
85632
|
async function reviewFrameGemini(framePath, intent, apiKey) {
|
|
85043
85633
|
try {
|
|
85044
|
-
const b642 =
|
|
85634
|
+
const b642 = readFileSync30(framePath).toString("base64");
|
|
85045
85635
|
const prompt = `This is a frame from an AI-generated video clip meant to show: "${intent}". Judge ONLY for obvious defects: melted/warped faces or hands, garbled text, broken anatomy, severe artifacts. Reply with STRICT JSON: {"acceptable": <true|false>, "note": "<\u226412 words, only if not acceptable>"}.`;
|
|
85046
85636
|
const res = await fetch(`${BASE_URL3}/models/${MODEL}:generateContent`, {
|
|
85047
85637
|
method: "POST",
|
|
@@ -85088,8 +85678,8 @@ function readDaemonKeyFile(name) {
|
|
|
85088
85678
|
try {
|
|
85089
85679
|
const home = tesseractHome();
|
|
85090
85680
|
const f = join38(home, "daemon", name);
|
|
85091
|
-
if (
|
|
85092
|
-
const k =
|
|
85681
|
+
if (existsSync17(f)) {
|
|
85682
|
+
const k = readFileSync31(f, "utf-8").trim();
|
|
85093
85683
|
if (k)
|
|
85094
85684
|
return k;
|
|
85095
85685
|
}
|
|
@@ -85248,7 +85838,7 @@ function createDaemonVideoEditRunner() {
|
|
|
85248
85838
|
if (!apiKey)
|
|
85249
85839
|
return { ok: false, error: "Voice cloning needs an ElevenLabs key (Settings \u2192 Voice)." };
|
|
85250
85840
|
try {
|
|
85251
|
-
const samples = sampleAudioPaths.slice(0, 25).map((p) => requireAbsolutePath(p, "sample audio path")).map((p) => ({ bytes: new Uint8Array(
|
|
85841
|
+
const samples = sampleAudioPaths.slice(0, 25).map((p) => requireAbsolutePath(p, "sample audio path")).map((p) => ({ bytes: new Uint8Array(readFileSync31(p)), mime: audioMimeForPath(p), filename: basename6(p) }));
|
|
85252
85842
|
const v = await cloneVoiceElevenLabs(name, samples, { apiKey, description });
|
|
85253
85843
|
return { ok: true, voiceId: v.voiceId, name: v.name };
|
|
85254
85844
|
} catch (e) {
|
|
@@ -85344,7 +85934,7 @@ function createDaemonVideoEditRunner() {
|
|
|
85344
85934
|
|
|
85345
85935
|
// ../../packages/host-core/dist/support-submit.js
|
|
85346
85936
|
init_credentials();
|
|
85347
|
-
import { openSync as
|
|
85937
|
+
import { openSync as openSync5, fstatSync, readSync as readSync4, closeSync as closeSync5 } from "node:fs";
|
|
85348
85938
|
import { join as join39 } from "node:path";
|
|
85349
85939
|
|
|
85350
85940
|
// ../../packages/host-core/dist/host-metrics.js
|
|
@@ -85384,19 +85974,19 @@ var LOG_TAIL_BYTES = 64 * 1024;
|
|
|
85384
85974
|
function tail2(path6, bytes2 = LOG_TAIL_BYTES) {
|
|
85385
85975
|
let fd = null;
|
|
85386
85976
|
try {
|
|
85387
|
-
fd =
|
|
85977
|
+
fd = openSync5(path6, "r");
|
|
85388
85978
|
const size = fstatSync(fd).size;
|
|
85389
85979
|
const len = Math.min(size, bytes2);
|
|
85390
85980
|
const start3 = Math.max(0, size - len);
|
|
85391
85981
|
const buf = Buffer.alloc(len);
|
|
85392
|
-
|
|
85982
|
+
readSync4(fd, buf, 0, len, start3);
|
|
85393
85983
|
return buf.toString("utf8");
|
|
85394
85984
|
} catch {
|
|
85395
85985
|
return "";
|
|
85396
85986
|
} finally {
|
|
85397
85987
|
if (fd !== null) {
|
|
85398
85988
|
try {
|
|
85399
|
-
|
|
85989
|
+
closeSync5(fd);
|
|
85400
85990
|
} catch {
|
|
85401
85991
|
}
|
|
85402
85992
|
}
|
|
@@ -86291,9 +86881,9 @@ async function replayTurn(turn) {
|
|
|
86291
86881
|
} catch {
|
|
86292
86882
|
}
|
|
86293
86883
|
for (const msg of terminal) {
|
|
86294
|
-
for (const
|
|
86884
|
+
for (const sink2 of [...sinks]) {
|
|
86295
86885
|
try {
|
|
86296
|
-
|
|
86886
|
+
sink2(msg, turn.params.origin);
|
|
86297
86887
|
} catch {
|
|
86298
86888
|
}
|
|
86299
86889
|
}
|
|
@@ -86333,10 +86923,10 @@ function drainBrowserEvents(params) {
|
|
|
86333
86923
|
return events;
|
|
86334
86924
|
}
|
|
86335
86925
|
setBrowserExtensionProbe(() => extensionBrowserConn != null);
|
|
86336
|
-
function registerAgentSink(
|
|
86337
|
-
sinks.add(
|
|
86926
|
+
function registerAgentSink(sink2) {
|
|
86927
|
+
sinks.add(sink2);
|
|
86338
86928
|
return () => {
|
|
86339
|
-
sinks.delete(
|
|
86929
|
+
sinks.delete(sink2);
|
|
86340
86930
|
};
|
|
86341
86931
|
}
|
|
86342
86932
|
function emitAgentEvent(msg, origin) {
|
|
@@ -86587,7 +87177,7 @@ function refreshDaemonScheduling(b) {
|
|
|
86587
87177
|
function daemonWorkspaceDir() {
|
|
86588
87178
|
const dir2 = tessPath("workspace");
|
|
86589
87179
|
try {
|
|
86590
|
-
|
|
87180
|
+
mkdirSync22(dir2, { recursive: true });
|
|
86591
87181
|
} catch {
|
|
86592
87182
|
}
|
|
86593
87183
|
return dir2;
|
|
@@ -86619,9 +87209,9 @@ function voiceUnavailableFrames(err2, reason) {
|
|
|
86619
87209
|
|
|
86620
87210
|
// ../../packages/host-core/dist/fs-remote.js
|
|
86621
87211
|
import { readdir as readdir4, readFile as readFile10, writeFile as writeFile9, mkdir as mkdir8, cp, rm as rm2, rename as renameAsync, stat as stat3 } from "node:fs/promises";
|
|
86622
|
-
import { openSync as
|
|
87212
|
+
import { openSync as openSync6, readSync as readSync5, writeSync, closeSync as closeSync6, statSync as statSync9, existsSync as existsSync18, mkdtempSync, rmSync as rmSync5, readFileSync as readFileSync32, readdirSync as readdirSync8, watch, realpathSync as realpathSync4, constants as fsConstants } from "node:fs";
|
|
86623
87213
|
import { tmpdir as tmpdir5 } from "node:os";
|
|
86624
|
-
import { basename as basename7, dirname as
|
|
87214
|
+
import { basename as basename7, dirname as dirname16, join as join42, relative as relative5, resolve as resolve8, sep as sep6, isAbsolute as isAbsolute6 } from "node:path";
|
|
86625
87215
|
import { execFile as execFile5 } from "node:child_process";
|
|
86626
87216
|
import { promisify as promisify2 } from "node:util";
|
|
86627
87217
|
|
|
@@ -86673,12 +87263,12 @@ async function dirStats(root, opts) {
|
|
|
86673
87263
|
}
|
|
86674
87264
|
async function codeStats(root) {
|
|
86675
87265
|
const start3 = Date.now();
|
|
86676
|
-
const MAX_FILES = 25e3,
|
|
87266
|
+
const MAX_FILES = 25e3, MAX_BYTES3 = 256 * 1024 * 1024, TIME_MS = 12e3;
|
|
86677
87267
|
const byLang = /* @__PURE__ */ new Map();
|
|
86678
87268
|
let totalFiles = 0, totalLines = 0, bytes2 = 0, truncated = false;
|
|
86679
87269
|
const stack = [root];
|
|
86680
87270
|
while (stack.length) {
|
|
86681
|
-
if (totalFiles >= MAX_FILES || bytes2 >=
|
|
87271
|
+
if (totalFiles >= MAX_FILES || bytes2 >= MAX_BYTES3 || Date.now() - start3 > TIME_MS) {
|
|
86682
87272
|
truncated = true;
|
|
86683
87273
|
break;
|
|
86684
87274
|
}
|
|
@@ -86690,7 +87280,7 @@ async function codeStats(root) {
|
|
|
86690
87280
|
continue;
|
|
86691
87281
|
}
|
|
86692
87282
|
for (const e of ents) {
|
|
86693
|
-
if (totalFiles >= MAX_FILES || bytes2 >=
|
|
87283
|
+
if (totalFiles >= MAX_FILES || bytes2 >= MAX_BYTES3 || Date.now() - start3 > TIME_MS) {
|
|
86694
87284
|
truncated = true;
|
|
86695
87285
|
break;
|
|
86696
87286
|
}
|
|
@@ -86921,14 +87511,14 @@ function resolveParent(raw, root) {
|
|
|
86921
87511
|
}
|
|
86922
87512
|
function resolveUniqueName(dir2, name) {
|
|
86923
87513
|
const direct = join42(dir2, name);
|
|
86924
|
-
if (!
|
|
87514
|
+
if (!existsSync18(direct))
|
|
86925
87515
|
return direct;
|
|
86926
87516
|
const dot = name.lastIndexOf(".");
|
|
86927
87517
|
const base = dot > 0 ? name.slice(0, dot) : name;
|
|
86928
87518
|
const ext = dot > 0 ? name.slice(dot) : "";
|
|
86929
87519
|
for (let i = 2; i < 1e4; i++) {
|
|
86930
87520
|
const candidate = join42(dir2, `${base} ${i}${ext}`);
|
|
86931
|
-
if (!
|
|
87521
|
+
if (!existsSync18(candidate))
|
|
86932
87522
|
return candidate;
|
|
86933
87523
|
}
|
|
86934
87524
|
return direct;
|
|
@@ -86962,7 +87552,7 @@ async function readRemoteBytes(root, path6) {
|
|
|
86962
87552
|
if (!real)
|
|
86963
87553
|
return { error: "Path is outside the shared root." };
|
|
86964
87554
|
try {
|
|
86965
|
-
const s =
|
|
87555
|
+
const s = statSync9(real);
|
|
86966
87556
|
if (!s.isFile())
|
|
86967
87557
|
return { error: "Not a file" };
|
|
86968
87558
|
if (s.size > REMOTE_READ_CAP)
|
|
@@ -86974,7 +87564,7 @@ async function readRemoteBytes(root, path6) {
|
|
|
86974
87564
|
}
|
|
86975
87565
|
var trashSeq = 0;
|
|
86976
87566
|
function statId(real) {
|
|
86977
|
-
const s =
|
|
87567
|
+
const s = statSync9(real, { bigint: true });
|
|
86978
87568
|
return {
|
|
86979
87569
|
size: Number(s.size),
|
|
86980
87570
|
mtimeMs: Number(s.mtimeMs),
|
|
@@ -87005,7 +87595,7 @@ async function renderThumbnailImpl(real, maxPx) {
|
|
|
87005
87595
|
const produced = readdirSync8(dir2).find((f) => f.toLowerCase().endsWith(".png"));
|
|
87006
87596
|
if (!produced)
|
|
87007
87597
|
return { error: "No thumbnail available." };
|
|
87008
|
-
return { png:
|
|
87598
|
+
return { png: readFileSync32(join42(dir2, produced)).toString("base64") };
|
|
87009
87599
|
} catch (err2) {
|
|
87010
87600
|
return { error: String(err2.message) };
|
|
87011
87601
|
} finally {
|
|
@@ -87046,7 +87636,7 @@ var SAFE_SEG = /^[A-Za-z0-9._-]+$/;
|
|
|
87046
87636
|
var TRASH_RETENTION_MS = 14 * 24 * 60 * 60 * 1e3;
|
|
87047
87637
|
function pruneTrash(root) {
|
|
87048
87638
|
const trashDir = join42(root, TRASH_DIR);
|
|
87049
|
-
if (!
|
|
87639
|
+
if (!existsSync18(trashDir))
|
|
87050
87640
|
return;
|
|
87051
87641
|
const cutoff = Date.now() - TRASH_RETENTION_MS;
|
|
87052
87642
|
try {
|
|
@@ -87054,7 +87644,7 @@ function pruneTrash(root) {
|
|
|
87054
87644
|
if (!e.isDirectory())
|
|
87055
87645
|
continue;
|
|
87056
87646
|
try {
|
|
87057
|
-
const meta4 = JSON.parse(
|
|
87647
|
+
const meta4 = JSON.parse(readFileSync32(join42(trashDir, e.name, ".fp-meta.json"), "utf-8"));
|
|
87058
87648
|
if ((meta4.deletedAt ?? 0) < cutoff)
|
|
87059
87649
|
rmSync5(join42(trashDir, e.name), { recursive: true, force: true });
|
|
87060
87650
|
} catch {
|
|
@@ -87121,7 +87711,7 @@ async function runRemoteFsOp(root, op, args, quotaKey) {
|
|
|
87121
87711
|
if (BINARY_EXT.has(ext))
|
|
87122
87712
|
return { error: "Binary file \u2014 not shown in the editor." };
|
|
87123
87713
|
try {
|
|
87124
|
-
const s =
|
|
87714
|
+
const s = statSync9(real);
|
|
87125
87715
|
if (s.size > TEXT_SIZE_LIMIT)
|
|
87126
87716
|
return { error: "File too large for text view." };
|
|
87127
87717
|
return { content: await readFile10(real, "utf-8") };
|
|
@@ -87136,7 +87726,7 @@ async function runRemoteFsOp(root, op, args, quotaKey) {
|
|
|
87136
87726
|
if (!real)
|
|
87137
87727
|
return OUTSIDE("write");
|
|
87138
87728
|
try {
|
|
87139
|
-
await mkdir8(
|
|
87729
|
+
await mkdir8(dirname16(real), { recursive: true });
|
|
87140
87730
|
await writeFile9(real, content, "utf-8");
|
|
87141
87731
|
return { ok: true };
|
|
87142
87732
|
} catch (err2) {
|
|
@@ -87150,7 +87740,7 @@ async function runRemoteFsOp(root, op, args, quotaKey) {
|
|
|
87150
87740
|
if (!real)
|
|
87151
87741
|
return OUTSIDE("write");
|
|
87152
87742
|
try {
|
|
87153
|
-
await mkdir8(
|
|
87743
|
+
await mkdir8(dirname16(real), { recursive: true });
|
|
87154
87744
|
await writeFile9(real, Buffer.from(base643, "base64"));
|
|
87155
87745
|
return { ok: true };
|
|
87156
87746
|
} catch (err2) {
|
|
@@ -87167,10 +87757,10 @@ async function runRemoteFsOp(root, op, args, quotaKey) {
|
|
|
87167
87757
|
let fd = null;
|
|
87168
87758
|
try {
|
|
87169
87759
|
if (off === 0) {
|
|
87170
|
-
await mkdir8(
|
|
87171
|
-
fd =
|
|
87760
|
+
await mkdir8(dirname16(real), { recursive: true });
|
|
87761
|
+
fd = openSync6(real, "w");
|
|
87172
87762
|
} else
|
|
87173
|
-
fd =
|
|
87763
|
+
fd = openSync6(real, "r+");
|
|
87174
87764
|
if (buf.length > 0)
|
|
87175
87765
|
writeSync(fd, buf, 0, buf.length, off);
|
|
87176
87766
|
return { ok: true, bytesWritten: buf.length };
|
|
@@ -87179,7 +87769,7 @@ async function runRemoteFsOp(root, op, args, quotaKey) {
|
|
|
87179
87769
|
} finally {
|
|
87180
87770
|
if (fd != null)
|
|
87181
87771
|
try {
|
|
87182
|
-
|
|
87772
|
+
closeSync6(fd);
|
|
87183
87773
|
} catch {
|
|
87184
87774
|
}
|
|
87185
87775
|
}
|
|
@@ -87221,16 +87811,16 @@ async function runRemoteFsOp(root, op, args, quotaKey) {
|
|
|
87221
87811
|
return { base64: "", bytesRead: 0 };
|
|
87222
87812
|
let fd = null;
|
|
87223
87813
|
try {
|
|
87224
|
-
fd =
|
|
87814
|
+
fd = openSync6(real, "r");
|
|
87225
87815
|
const buf = Buffer.alloc(len);
|
|
87226
|
-
const bytesRead =
|
|
87816
|
+
const bytesRead = readSync5(fd, buf, 0, len, off);
|
|
87227
87817
|
return { base64: buf.subarray(0, bytesRead).toString("base64"), bytesRead };
|
|
87228
87818
|
} catch (err2) {
|
|
87229
87819
|
return { error: String(err2.message) };
|
|
87230
87820
|
} finally {
|
|
87231
87821
|
if (fd != null)
|
|
87232
87822
|
try {
|
|
87233
|
-
|
|
87823
|
+
closeSync6(fd);
|
|
87234
87824
|
} catch {
|
|
87235
87825
|
}
|
|
87236
87826
|
}
|
|
@@ -87241,7 +87831,7 @@ async function runRemoteFsOp(root, op, args, quotaKey) {
|
|
|
87241
87831
|
if (!real)
|
|
87242
87832
|
return { error: "Path is outside the shared root." };
|
|
87243
87833
|
try {
|
|
87244
|
-
const s =
|
|
87834
|
+
const s = statSync9(real);
|
|
87245
87835
|
if (s.size > REMOTE_READ_CAP)
|
|
87246
87836
|
return { error: `File is too large to read whole over the network (${(s.size / 1024 / 1024).toFixed(1)} MB) \u2014 open it locally.` };
|
|
87247
87837
|
return { base64: (await readFile10(real)).toString("base64"), size: s.size };
|
|
@@ -87257,7 +87847,7 @@ async function runRemoteFsOp(root, op, args, quotaKey) {
|
|
|
87257
87847
|
const target = join42(parent, name);
|
|
87258
87848
|
if (!insideOk(target))
|
|
87259
87849
|
return { ok: false, error: "Refusing to create a project outside the shared root." };
|
|
87260
|
-
if (
|
|
87850
|
+
if (existsSync18(target))
|
|
87261
87851
|
return { ok: false, error: `A folder named "${name}" already exists.` };
|
|
87262
87852
|
try {
|
|
87263
87853
|
await mkdir8(target, { recursive: true });
|
|
@@ -87275,7 +87865,7 @@ async function runRemoteFsOp(root, op, args, quotaKey) {
|
|
|
87275
87865
|
const target = join42(parent, name);
|
|
87276
87866
|
if (!insideOk(target))
|
|
87277
87867
|
return OUTSIDE("create");
|
|
87278
|
-
if (
|
|
87868
|
+
if (existsSync18(target))
|
|
87279
87869
|
return { ok: false, error: `"${name}" already exists.` };
|
|
87280
87870
|
try {
|
|
87281
87871
|
if (op === "createFile")
|
|
@@ -87294,8 +87884,8 @@ async function runRemoteFsOp(root, op, args, quotaKey) {
|
|
|
87294
87884
|
return { ok: false, error: "Invalid name." };
|
|
87295
87885
|
if (!insideOk(oldPath))
|
|
87296
87886
|
return OUTSIDE("rename");
|
|
87297
|
-
const newPath = join42(
|
|
87298
|
-
if (
|
|
87887
|
+
const newPath = join42(dirname16(oldPath), newName);
|
|
87888
|
+
if (existsSync18(newPath))
|
|
87299
87889
|
return { ok: false, error: `A file named "${newName}" already exists.` };
|
|
87300
87890
|
try {
|
|
87301
87891
|
await renameAsync(oldPath, newPath);
|
|
@@ -87341,7 +87931,7 @@ async function runRemoteFsOp(root, op, args, quotaKey) {
|
|
|
87341
87931
|
}
|
|
87342
87932
|
case "listTrash": {
|
|
87343
87933
|
const trashDir = join42(root, TRASH_DIR);
|
|
87344
|
-
if (!
|
|
87934
|
+
if (!existsSync18(trashDir))
|
|
87345
87935
|
return [];
|
|
87346
87936
|
try {
|
|
87347
87937
|
const out = [];
|
|
@@ -87349,7 +87939,7 @@ async function runRemoteFsOp(root, op, args, quotaKey) {
|
|
|
87349
87939
|
if (!e.isDirectory())
|
|
87350
87940
|
continue;
|
|
87351
87941
|
try {
|
|
87352
|
-
const meta4 = JSON.parse(
|
|
87942
|
+
const meta4 = JSON.parse(readFileSync32(join42(trashDir, e.name, ".fp-meta.json"), "utf-8"));
|
|
87353
87943
|
out.push({ trashId: e.name, name: meta4.name, path: join42(trashDir, e.name, meta4.name), originalPath: meta4.originalPath, deletedAt: meta4.deletedAt });
|
|
87354
87944
|
} catch {
|
|
87355
87945
|
}
|
|
@@ -87364,19 +87954,19 @@ async function runRemoteFsOp(root, op, args, quotaKey) {
|
|
|
87364
87954
|
if (!SAFE_SEG.test(id))
|
|
87365
87955
|
return { ok: false, error: "Bad trash id." };
|
|
87366
87956
|
const itemDir = join42(root, TRASH_DIR, id);
|
|
87367
|
-
if (!
|
|
87957
|
+
if (!existsSync18(itemDir))
|
|
87368
87958
|
return { ok: false, error: "Not in trash." };
|
|
87369
87959
|
try {
|
|
87370
|
-
const meta4 = JSON.parse(
|
|
87960
|
+
const meta4 = JSON.parse(readFileSync32(join42(itemDir, ".fp-meta.json"), "utf-8"));
|
|
87371
87961
|
if (!validName(meta4.name))
|
|
87372
87962
|
return { ok: false, error: "Bad trashed name." };
|
|
87373
87963
|
const src = join42(itemDir, meta4.name);
|
|
87374
87964
|
let dest = meta4.originalPath;
|
|
87375
87965
|
if (!insideOk(dest))
|
|
87376
87966
|
return OUTSIDE("restore");
|
|
87377
|
-
if (
|
|
87378
|
-
dest = resolveUniqueName(
|
|
87379
|
-
await mkdir8(
|
|
87967
|
+
if (existsSync18(dest))
|
|
87968
|
+
dest = resolveUniqueName(dirname16(dest), meta4.name);
|
|
87969
|
+
await mkdir8(dirname16(dest), { recursive: true });
|
|
87380
87970
|
await moveItem(src, dest);
|
|
87381
87971
|
rmSync5(itemDir, { recursive: true, force: true });
|
|
87382
87972
|
return { ok: true, path: dest };
|
|
@@ -87397,7 +87987,7 @@ async function runRemoteFsOp(root, op, args, quotaKey) {
|
|
|
87397
87987
|
continue;
|
|
87398
87988
|
if (!insideOk(src))
|
|
87399
87989
|
return OUTSIDE(op === "copyPaths" ? "copy from" : "move from");
|
|
87400
|
-
if (op === "movePaths" &&
|
|
87990
|
+
if (op === "movePaths" && dirname16(src) === destDir) {
|
|
87401
87991
|
newPaths.push(src);
|
|
87402
87992
|
continue;
|
|
87403
87993
|
}
|
|
@@ -87678,8 +88268,8 @@ function releaseDcClient(clientId) {
|
|
|
87678
88268
|
|
|
87679
88269
|
// ../../packages/host-core/dist/fs-transfer.js
|
|
87680
88270
|
import { readdir as readdir5, lstat as lstat2, mkdir as mkdir9, chmod, rm as rm3, readlink, symlink, stat as stat4 } from "node:fs/promises";
|
|
87681
|
-
import { openSync as
|
|
87682
|
-
import { basename as basename8, dirname as
|
|
88271
|
+
import { openSync as openSync7, readSync as readSync6, closeSync as closeSync7, existsSync as existsSync19, createWriteStream } from "node:fs";
|
|
88272
|
+
import { basename as basename8, dirname as dirname17, join as join44, relative as relative7, sep as sep8 } from "node:path";
|
|
87683
88273
|
|
|
87684
88274
|
// ../../packages/host-core/dist/active-link/paths.js
|
|
87685
88275
|
init_base_paths();
|
|
@@ -87735,7 +88325,7 @@ function clearTimer(t) {
|
|
|
87735
88325
|
}
|
|
87736
88326
|
function uniqueDir(parent, name) {
|
|
87737
88327
|
let candidate = join44(parent, name);
|
|
87738
|
-
for (let i = 2;
|
|
88328
|
+
for (let i = 2; existsSync19(candidate) && i < 1e4; i++)
|
|
87739
88329
|
candidate = join44(parent, `${name} ${i}`);
|
|
87740
88330
|
return candidate;
|
|
87741
88331
|
}
|
|
@@ -87744,7 +88334,7 @@ function uniqueFile(parent, name) {
|
|
|
87744
88334
|
const stem = dot > 0 ? name.slice(0, dot) : name;
|
|
87745
88335
|
const ext = dot > 0 ? name.slice(dot) : "";
|
|
87746
88336
|
let candidate = join44(parent, name);
|
|
87747
|
-
for (let i = 2;
|
|
88337
|
+
for (let i = 2; existsSync19(candidate) && i < 1e4; i++)
|
|
87748
88338
|
candidate = join44(parent, `${stem} ${i}${ext}`);
|
|
87749
88339
|
return candidate;
|
|
87750
88340
|
}
|
|
@@ -87874,7 +88464,7 @@ async function startOutboundTransfer(msg, controllerClientId, ownHostId2, hostRo
|
|
|
87874
88464
|
producers.delete(transferId);
|
|
87875
88465
|
return;
|
|
87876
88466
|
}
|
|
87877
|
-
const srcBase = manifest.singleFile ?
|
|
88467
|
+
const srcBase = manifest.singleFile ? dirname17(srcPath) : srcPath;
|
|
87878
88468
|
send4({
|
|
87879
88469
|
type: "fs:transferManifest",
|
|
87880
88470
|
transferId,
|
|
@@ -87902,7 +88492,7 @@ async function startOutboundTransfer(msg, controllerClientId, ownHostId2, hostRo
|
|
|
87902
88492
|
const abs = join44(srcBase, f.rel.split("/").join(sep8));
|
|
87903
88493
|
let fd = null;
|
|
87904
88494
|
try {
|
|
87905
|
-
fd =
|
|
88495
|
+
fd = openSync7(abs, "r");
|
|
87906
88496
|
if (f.size === 0) {
|
|
87907
88497
|
send4({ type: "fs:transferChunk", transferId, toHost, fileIx, rel: f.rel, mode: f.mode, kind: "file", offset: 0, base64: "", eof: true }, { hostId: toHost });
|
|
87908
88498
|
} else {
|
|
@@ -87912,7 +88502,7 @@ async function startOutboundTransfer(msg, controllerClientId, ownHostId2, hostRo
|
|
|
87912
88502
|
break;
|
|
87913
88503
|
const len = Math.min(CHUNK2, f.size - offset);
|
|
87914
88504
|
const buf = Buffer.alloc(len);
|
|
87915
|
-
const read =
|
|
88505
|
+
const read = readSync6(fd, buf, 0, len, offset);
|
|
87916
88506
|
send4({ type: "fs:transferChunk", transferId, toHost, fileIx, rel: f.rel, mode: f.mode, kind: "file", offset, base64: buf.subarray(0, read).toString("base64"), eof: offset + len >= f.size }, { hostId: toHost });
|
|
87917
88507
|
state3.sentBytes += read;
|
|
87918
88508
|
}
|
|
@@ -87920,7 +88510,7 @@ async function startOutboundTransfer(msg, controllerClientId, ownHostId2, hostRo
|
|
|
87920
88510
|
} catch (e) {
|
|
87921
88511
|
if (fd != null)
|
|
87922
88512
|
try {
|
|
87923
|
-
|
|
88513
|
+
closeSync7(fd);
|
|
87924
88514
|
} catch {
|
|
87925
88515
|
}
|
|
87926
88516
|
failProducer(transferId, `Couldn't read ${f.rel}: ${e.message}`);
|
|
@@ -87928,7 +88518,7 @@ async function startOutboundTransfer(msg, controllerClientId, ownHostId2, hostRo
|
|
|
87928
88518
|
} finally {
|
|
87929
88519
|
if (fd != null)
|
|
87930
88520
|
try {
|
|
87931
|
-
|
|
88521
|
+
closeSync7(fd);
|
|
87932
88522
|
} catch {
|
|
87933
88523
|
}
|
|
87934
88524
|
}
|
|
@@ -88041,7 +88631,7 @@ async function beginInboundTransfer(msg, hostRoot, send4) {
|
|
|
88041
88631
|
if (msg.singleFile) {
|
|
88042
88632
|
let destFile = join44(parent, msg.destName);
|
|
88043
88633
|
let createdFile = true;
|
|
88044
|
-
if (
|
|
88634
|
+
if (existsSync19(destFile)) {
|
|
88045
88635
|
if (msg.onCollision === "abort") {
|
|
88046
88636
|
failNoState(`"${msg.destName}" already exists on the destination.`);
|
|
88047
88637
|
return;
|
|
@@ -88066,7 +88656,7 @@ async function beginInboundTransfer(msg, hostRoot, send4) {
|
|
|
88066
88656
|
}
|
|
88067
88657
|
let destRoot = join44(parent, msg.destName);
|
|
88068
88658
|
let createdRoot = false;
|
|
88069
|
-
if (
|
|
88659
|
+
if (existsSync19(destRoot)) {
|
|
88070
88660
|
if (msg.onCollision === "abort") {
|
|
88071
88661
|
failNoState(`"${msg.destName}" already exists on the destination.`);
|
|
88072
88662
|
return;
|
|
@@ -88112,9 +88702,9 @@ async function writeInboundChunk(msg, send4) {
|
|
|
88112
88702
|
try {
|
|
88113
88703
|
if (msg.kind === "symlink") {
|
|
88114
88704
|
const target = Buffer.from(msg.base64, "base64").toString("utf-8");
|
|
88115
|
-
const resolved = join44(
|
|
88705
|
+
const resolved = join44(dirname17(abs), target);
|
|
88116
88706
|
if (isInsideRoot(resolved, s.destRoot)) {
|
|
88117
|
-
await mkdir9(
|
|
88707
|
+
await mkdir9(dirname17(abs), { recursive: true }).catch(() => {
|
|
88118
88708
|
});
|
|
88119
88709
|
await symlink(target, abs).catch(() => {
|
|
88120
88710
|
});
|
|
@@ -88127,7 +88717,7 @@ async function writeInboundChunk(msg, send4) {
|
|
|
88127
88717
|
if (s.curIx !== msg.fileIx || !s.curStream) {
|
|
88128
88718
|
if (s.curStream)
|
|
88129
88719
|
await new Promise((r) => s.curStream.end(r));
|
|
88130
|
-
await mkdir9(
|
|
88720
|
+
await mkdir9(dirname17(abs), { recursive: true }).catch(() => {
|
|
88131
88721
|
});
|
|
88132
88722
|
s.curStream = createWriteStream(abs);
|
|
88133
88723
|
s.curIx = msg.fileIx;
|
|
@@ -88723,12 +89313,12 @@ init_credentials();
|
|
|
88723
89313
|
init_credentials();
|
|
88724
89314
|
import { hostname as hostname3, platform } from "node:os";
|
|
88725
89315
|
import { randomUUID as randomUUID21 } from "node:crypto";
|
|
88726
|
-
import { chmodSync as chmodSync3, existsSync as
|
|
89316
|
+
import { chmodSync as chmodSync3, existsSync as existsSync21, mkdirSync as mkdirSync24, readFileSync as readFileSync34, writeFileSync as writeFileSync23 } from "node:fs";
|
|
88727
89317
|
import { join as join46 } from "node:path";
|
|
88728
89318
|
var FILE = () => join46(daemonDir2(), "machine-identity.json");
|
|
88729
89319
|
function readMachineIdentity() {
|
|
88730
89320
|
try {
|
|
88731
|
-
const m = JSON.parse(
|
|
89321
|
+
const m = JSON.parse(readFileSync34(FILE(), "utf-8"));
|
|
88732
89322
|
return m?.deviceToken && m?.publicId ? m : null;
|
|
88733
89323
|
} catch {
|
|
88734
89324
|
return null;
|
|
@@ -88736,7 +89326,7 @@ function readMachineIdentity() {
|
|
|
88736
89326
|
}
|
|
88737
89327
|
function write(m) {
|
|
88738
89328
|
try {
|
|
88739
|
-
|
|
89329
|
+
mkdirSync24(daemonDir2(), { recursive: true, mode: 448 });
|
|
88740
89330
|
writeFileSync23(FILE(), JSON.stringify(m, null, 2), { mode: 384 });
|
|
88741
89331
|
chmodSync3(FILE(), 384);
|
|
88742
89332
|
} catch {
|
|
@@ -88832,14 +89422,14 @@ function getMachinePublicId() {
|
|
|
88832
89422
|
|
|
88833
89423
|
// ../../packages/host-core/dist/active-link/engine.js
|
|
88834
89424
|
import { lstat as lstat7, readlink as readlink4, rm as rm4, mkdir as mkdir11, symlink as symlink2, rename as rename2, utimes as utimes2, writeFile as writeFile10 } from "node:fs/promises";
|
|
88835
|
-
import { existsSync as
|
|
88836
|
-
import { dirname as
|
|
89425
|
+
import { existsSync as existsSync23 } from "node:fs";
|
|
89426
|
+
import { dirname as dirname22, join as join51, resolve as resolve11 } from "node:path";
|
|
88837
89427
|
|
|
88838
89428
|
// ../../packages/host-core/dist/active-link/blocks.js
|
|
88839
89429
|
import { createHash as createHash4 } from "node:crypto";
|
|
88840
89430
|
import { createReadStream } from "node:fs";
|
|
88841
89431
|
import { open, mkdir as mkdir10, rename, chmod as chmod2, utimes, unlink } from "node:fs/promises";
|
|
88842
|
-
import { dirname as
|
|
89432
|
+
import { dirname as dirname19 } from "node:path";
|
|
88843
89433
|
var CHUNK3 = 1024 * 1024;
|
|
88844
89434
|
var MAX_INFLIGHT2 = 8 * CHUNK3;
|
|
88845
89435
|
var IDLE_MS2 = 6e4;
|
|
@@ -88967,7 +89557,7 @@ var StagingWriter = class {
|
|
|
88967
89557
|
}
|
|
88968
89558
|
async ensureOpen() {
|
|
88969
89559
|
if (!this.fh) {
|
|
88970
|
-
await mkdir10(
|
|
89560
|
+
await mkdir10(dirname19(this.stagingPath), { recursive: true });
|
|
88971
89561
|
this.fh = await open(this.stagingPath, "w");
|
|
88972
89562
|
}
|
|
88973
89563
|
return this.fh;
|
|
@@ -88997,7 +89587,7 @@ var StagingWriter = class {
|
|
|
88997
89587
|
});
|
|
88998
89588
|
await fh.close();
|
|
88999
89589
|
this.fh = null;
|
|
89000
|
-
await mkdir10(
|
|
89590
|
+
await mkdir10(dirname19(dest), { recursive: true });
|
|
89001
89591
|
await chmod2(this.stagingPath, mode & 511).catch(() => {
|
|
89002
89592
|
});
|
|
89003
89593
|
const secs = mtimeMs / 1e3;
|
|
@@ -89030,7 +89620,7 @@ var BlockAssembler = class {
|
|
|
89030
89620
|
this.stagingPath = stagingPath;
|
|
89031
89621
|
}
|
|
89032
89622
|
async open() {
|
|
89033
|
-
await mkdir10(
|
|
89623
|
+
await mkdir10(dirname19(this.stagingPath), { recursive: true });
|
|
89034
89624
|
this.fh = await open(this.stagingPath, "w");
|
|
89035
89625
|
}
|
|
89036
89626
|
/** Write a received block at its byte offset (index * CHUNK). */
|
|
@@ -89074,7 +89664,7 @@ var BlockAssembler = class {
|
|
|
89074
89664
|
});
|
|
89075
89665
|
return false;
|
|
89076
89666
|
}
|
|
89077
|
-
await mkdir10(
|
|
89667
|
+
await mkdir10(dirname19(dest), { recursive: true });
|
|
89078
89668
|
await chmod2(this.stagingPath, mode & 511).catch(() => {
|
|
89079
89669
|
});
|
|
89080
89670
|
const secs = mtimeMs / 1e3;
|
|
@@ -89097,7 +89687,7 @@ var BlockAssembler = class {
|
|
|
89097
89687
|
};
|
|
89098
89688
|
|
|
89099
89689
|
// ../../packages/host-core/dist/active-link/manifest.js
|
|
89100
|
-
import { readFileSync as
|
|
89690
|
+
import { readFileSync as readFileSync35, writeFileSync as writeFileSync24, mkdirSync as mkdirSync25, existsSync as existsSync22, renameSync as renameSync8 } from "node:fs";
|
|
89101
89691
|
import { join as join47 } from "node:path";
|
|
89102
89692
|
|
|
89103
89693
|
// ../../packages/host-core/dist/active-link/reconcile.js
|
|
@@ -89138,7 +89728,7 @@ var LinkManifest = class {
|
|
|
89138
89728
|
}
|
|
89139
89729
|
load() {
|
|
89140
89730
|
try {
|
|
89141
|
-
const raw = JSON.parse(
|
|
89731
|
+
const raw = JSON.parse(readFileSync35(this.file(), "utf-8"));
|
|
89142
89732
|
this.records = new Map(Object.entries(raw.records ?? {}));
|
|
89143
89733
|
this.tombstones = new Map(Object.entries(raw.tombstones ?? {}));
|
|
89144
89734
|
} catch {
|
|
@@ -89219,15 +89809,15 @@ var LinkManifest = class {
|
|
|
89219
89809
|
if (!this.dirty)
|
|
89220
89810
|
return;
|
|
89221
89811
|
try {
|
|
89222
|
-
if (!
|
|
89223
|
-
|
|
89812
|
+
if (!existsSync22(this.dir))
|
|
89813
|
+
mkdirSync25(this.dir, { recursive: true });
|
|
89224
89814
|
const json3 = {
|
|
89225
89815
|
records: Object.fromEntries(this.records),
|
|
89226
89816
|
tombstones: Object.fromEntries(this.tombstones)
|
|
89227
89817
|
};
|
|
89228
89818
|
const tmp = `${this.file()}.tmp`;
|
|
89229
89819
|
writeFileSync24(tmp, JSON.stringify(json3));
|
|
89230
|
-
|
|
89820
|
+
renameSync8(tmp, this.file());
|
|
89231
89821
|
this.dirty = false;
|
|
89232
89822
|
} catch {
|
|
89233
89823
|
}
|
|
@@ -90236,9 +90826,9 @@ var NodeFsHandler = class {
|
|
|
90236
90826
|
if (this.fsw.closed) {
|
|
90237
90827
|
return;
|
|
90238
90828
|
}
|
|
90239
|
-
const
|
|
90829
|
+
const dirname33 = sysPath.dirname(file2);
|
|
90240
90830
|
const basename14 = sysPath.basename(file2);
|
|
90241
|
-
const parent = this.fsw._getWatchedDir(
|
|
90831
|
+
const parent = this.fsw._getWatchedDir(dirname33);
|
|
90242
90832
|
let prevStats = stats;
|
|
90243
90833
|
if (parent.has(basename14))
|
|
90244
90834
|
return;
|
|
@@ -90265,7 +90855,7 @@ var NodeFsHandler = class {
|
|
|
90265
90855
|
prevStats = newStats2;
|
|
90266
90856
|
}
|
|
90267
90857
|
} catch (error51) {
|
|
90268
|
-
this.fsw._remove(
|
|
90858
|
+
this.fsw._remove(dirname33, basename14);
|
|
90269
90859
|
}
|
|
90270
90860
|
} else if (parent.has(basename14)) {
|
|
90271
90861
|
const at = newStats.atimeMs;
|
|
@@ -91710,13 +92300,13 @@ var ActiveLinkEngine = class {
|
|
|
91710
92300
|
* file so the path still exists — recorded as a FILE matching disk so the local
|
|
91711
92301
|
* watcher doesn't churn. The target is containment-checked, never dereferenced. */
|
|
91712
92302
|
async applySymlink(rel, dest, target, mtimeMs, mode) {
|
|
91713
|
-
const resolved = resolve11(
|
|
92303
|
+
const resolved = resolve11(dirname22(dest), target);
|
|
91714
92304
|
if (!isInsideRoot(resolved, this.opts.localRoot))
|
|
91715
92305
|
return;
|
|
91716
92306
|
const hash2 = hashString(target);
|
|
91717
92307
|
const secs = mtimeMs / 1e3;
|
|
91718
92308
|
try {
|
|
91719
|
-
await mkdir11(
|
|
92309
|
+
await mkdir11(dirname22(dest), { recursive: true });
|
|
91720
92310
|
await rm4(dest, { force: true, recursive: true });
|
|
91721
92311
|
try {
|
|
91722
92312
|
await symlink2(target, dest);
|
|
@@ -91768,7 +92358,7 @@ var ActiveLinkEngine = class {
|
|
|
91768
92358
|
return;
|
|
91769
92359
|
if (fromRec && fromRec.kind === "file") {
|
|
91770
92360
|
try {
|
|
91771
|
-
await mkdir11(
|
|
92361
|
+
await mkdir11(dirname22(toAbs2), { recursive: true });
|
|
91772
92362
|
await rename2(fromAbs, toAbs2);
|
|
91773
92363
|
const secs = mtimeMs / 1e3;
|
|
91774
92364
|
await utimes2(toAbs2, secs, secs).catch(() => {
|
|
@@ -91793,7 +92383,7 @@ var ActiveLinkEngine = class {
|
|
|
91793
92383
|
await this.maybeRefreshAllow(rels);
|
|
91794
92384
|
const state3 = /* @__PURE__ */ new Map();
|
|
91795
92385
|
for (const rel of rels) {
|
|
91796
|
-
if (
|
|
92386
|
+
if (existsSync23(absOf(this.opts.localRoot, rel)) && !this.isSynced(rel)) {
|
|
91797
92387
|
this.manifest.dropRecord(rel);
|
|
91798
92388
|
continue;
|
|
91799
92389
|
}
|
|
@@ -91897,7 +92487,7 @@ var ActiveLinkEngine = class {
|
|
|
91897
92487
|
for (const rel of this.manifest.recordRels()) {
|
|
91898
92488
|
if (records.has(rel))
|
|
91899
92489
|
continue;
|
|
91900
|
-
if (
|
|
92490
|
+
if (existsSync23(absOf(this.opts.localRoot, rel)))
|
|
91901
92491
|
this.manifest.dropRecord(rel);
|
|
91902
92492
|
else
|
|
91903
92493
|
this.manifest.setTombstone(rel, now2);
|
|
@@ -91968,14 +92558,14 @@ var ActiveLinkEngine = class {
|
|
|
91968
92558
|
};
|
|
91969
92559
|
|
|
91970
92560
|
// ../../packages/host-core/dist/active-link/config.js
|
|
91971
|
-
import { readFileSync as
|
|
92561
|
+
import { readFileSync as readFileSync36, writeFileSync as writeFileSync25, mkdirSync as mkdirSync26, existsSync as existsSync24, renameSync as renameSync9, watch as watch3 } from "node:fs";
|
|
91972
92562
|
import { join as join52 } from "node:path";
|
|
91973
92563
|
function configPath2() {
|
|
91974
92564
|
return join52(activeLinkRoot(), "links.json");
|
|
91975
92565
|
}
|
|
91976
92566
|
function loadLinkConfigs() {
|
|
91977
92567
|
try {
|
|
91978
|
-
const raw = JSON.parse(
|
|
92568
|
+
const raw = JSON.parse(readFileSync36(configPath2(), "utf-8"));
|
|
91979
92569
|
if (!Array.isArray(raw.links))
|
|
91980
92570
|
return [];
|
|
91981
92571
|
return raw.links.filter((c) => c && c.linkId && c.localRoot && c.peerHostId);
|
|
@@ -91986,11 +92576,11 @@ function loadLinkConfigs() {
|
|
|
91986
92576
|
function writeAll(links) {
|
|
91987
92577
|
try {
|
|
91988
92578
|
const dir2 = activeLinkRoot();
|
|
91989
|
-
if (!
|
|
91990
|
-
|
|
92579
|
+
if (!existsSync24(dir2))
|
|
92580
|
+
mkdirSync26(dir2, { recursive: true });
|
|
91991
92581
|
const tmp = `${configPath2()}.tmp`;
|
|
91992
92582
|
writeFileSync25(tmp, JSON.stringify({ links }, null, 2));
|
|
91993
|
-
|
|
92583
|
+
renameSync9(tmp, configPath2());
|
|
91994
92584
|
} catch {
|
|
91995
92585
|
}
|
|
91996
92586
|
}
|
|
@@ -92012,7 +92602,7 @@ function pendingPath() {
|
|
|
92012
92602
|
}
|
|
92013
92603
|
function loadPendingDeprovisions() {
|
|
92014
92604
|
try {
|
|
92015
|
-
const raw = JSON.parse(
|
|
92605
|
+
const raw = JSON.parse(readFileSync36(pendingPath(), "utf-8"));
|
|
92016
92606
|
return Array.isArray(raw.pending) ? raw.pending.filter((p) => p && p.linkId && p.peerHostId) : [];
|
|
92017
92607
|
} catch {
|
|
92018
92608
|
return [];
|
|
@@ -92021,11 +92611,11 @@ function loadPendingDeprovisions() {
|
|
|
92021
92611
|
function writePending(pending2) {
|
|
92022
92612
|
try {
|
|
92023
92613
|
const dir2 = activeLinkRoot();
|
|
92024
|
-
if (!
|
|
92025
|
-
|
|
92614
|
+
if (!existsSync24(dir2))
|
|
92615
|
+
mkdirSync26(dir2, { recursive: true });
|
|
92026
92616
|
const tmp = `${pendingPath()}.tmp`;
|
|
92027
92617
|
writeFileSync25(tmp, JSON.stringify({ pending: pending2 }, null, 2));
|
|
92028
|
-
|
|
92618
|
+
renameSync9(tmp, pendingPath());
|
|
92029
92619
|
} catch {
|
|
92030
92620
|
}
|
|
92031
92621
|
}
|
|
@@ -92037,8 +92627,8 @@ function removeLinkConfig(linkId) {
|
|
|
92037
92627
|
}
|
|
92038
92628
|
function watchLinkConfigs(onChange) {
|
|
92039
92629
|
const dir2 = activeLinkRoot();
|
|
92040
|
-
if (!
|
|
92041
|
-
|
|
92630
|
+
if (!existsSync24(dir2))
|
|
92631
|
+
mkdirSync26(dir2, { recursive: true });
|
|
92042
92632
|
let timer2 = null;
|
|
92043
92633
|
let watcher = null;
|
|
92044
92634
|
try {
|
|
@@ -92183,7 +92773,7 @@ function routeInboundLinkFrame(frame) {
|
|
|
92183
92773
|
init_dist5();
|
|
92184
92774
|
|
|
92185
92775
|
// ../../packages/host-core/dist/pty-manager.js
|
|
92186
|
-
import { existsSync as
|
|
92776
|
+
import { existsSync as existsSync25 } from "node:fs";
|
|
92187
92777
|
import { homedir as homedir8 } from "node:os";
|
|
92188
92778
|
var ptyPromise = null;
|
|
92189
92779
|
function loadPty() {
|
|
@@ -92205,7 +92795,7 @@ function key(clientId, ptyId) {
|
|
|
92205
92795
|
var sessions2 = /* @__PURE__ */ new Map();
|
|
92206
92796
|
var FLUSH_MS = 8;
|
|
92207
92797
|
var FLUSH_BYTES = 64 * 1024;
|
|
92208
|
-
function flush(ptyId, s,
|
|
92798
|
+
function flush(ptyId, s, sink2) {
|
|
92209
92799
|
if (s.timer) {
|
|
92210
92800
|
clearTimeout(s.timer);
|
|
92211
92801
|
s.timer = null;
|
|
@@ -92215,9 +92805,9 @@ function flush(ptyId, s, sink) {
|
|
|
92215
92805
|
const joined = s.buf.join("");
|
|
92216
92806
|
s.buf = [];
|
|
92217
92807
|
s.bytes = 0;
|
|
92218
|
-
|
|
92808
|
+
sink2.output(ptyId, Buffer.from(joined, "utf8").toString("base64"));
|
|
92219
92809
|
}
|
|
92220
|
-
async function openPty(opts,
|
|
92810
|
+
async function openPty(opts, sink2) {
|
|
92221
92811
|
const pty = await loadPty();
|
|
92222
92812
|
if (!pty)
|
|
92223
92813
|
throw new Error("Terminal support is unavailable on this machine.");
|
|
@@ -92247,14 +92837,14 @@ async function openPty(opts, sink) {
|
|
|
92247
92837
|
s.buf.push(data);
|
|
92248
92838
|
s.bytes += data.length;
|
|
92249
92839
|
if (s.bytes >= FLUSH_BYTES)
|
|
92250
|
-
flush(opts.ptyId, s,
|
|
92840
|
+
flush(opts.ptyId, s, sink2);
|
|
92251
92841
|
else if (!s.timer)
|
|
92252
|
-
s.timer = setTimeout(() => flush(opts.ptyId, s,
|
|
92842
|
+
s.timer = setTimeout(() => flush(opts.ptyId, s, sink2), FLUSH_MS);
|
|
92253
92843
|
});
|
|
92254
92844
|
proc.onExit(({ exitCode, signal }) => {
|
|
92255
|
-
flush(opts.ptyId, s,
|
|
92845
|
+
flush(opts.ptyId, s, sink2);
|
|
92256
92846
|
sessions2.delete(k);
|
|
92257
|
-
|
|
92847
|
+
sink2.exit(opts.ptyId, exitCode ?? null, signal ?? null);
|
|
92258
92848
|
});
|
|
92259
92849
|
return { pid: proc.pid };
|
|
92260
92850
|
}
|
|
@@ -92346,7 +92936,7 @@ function listUnix() {
|
|
|
92346
92936
|
const seen = /* @__PURE__ */ new Set();
|
|
92347
92937
|
const loginShell = process.env.SHELL || "";
|
|
92348
92938
|
const add2 = (id, path6) => {
|
|
92349
|
-
if (!path6 || seen.has(path6) || !
|
|
92939
|
+
if (!path6 || seen.has(path6) || !existsSync25(path6))
|
|
92350
92940
|
return;
|
|
92351
92941
|
seen.add(path6);
|
|
92352
92942
|
out.push(mk(id, path6, path6 === loginShell));
|
|
@@ -92378,7 +92968,7 @@ function listWindows() {
|
|
|
92378
92968
|
const gitBash = `${pf}\\Git\\bin\\bash.exe`;
|
|
92379
92969
|
const pwsh7 = `${pf}\\PowerShell\\7\\pwsh.exe`;
|
|
92380
92970
|
const add2 = (id, path6, label, isDefault = false) => {
|
|
92381
|
-
if (path6 &&
|
|
92971
|
+
if (path6 && existsSync25(path6))
|
|
92382
92972
|
out.push(mk(id, path6, isDefault, label));
|
|
92383
92973
|
};
|
|
92384
92974
|
add2("powershell", winPwsh, "Windows PowerShell", true);
|
|
@@ -92437,7 +93027,7 @@ function resolveCwd(cwd, hostRoot) {
|
|
|
92437
93027
|
const fallback = hostRoot || homedir8();
|
|
92438
93028
|
if (!cwd)
|
|
92439
93029
|
return fallback;
|
|
92440
|
-
if (!
|
|
93030
|
+
if (!existsSync25(cwd))
|
|
92441
93031
|
return fallback;
|
|
92442
93032
|
if (hostRoot && !isInsideRoot(cwd, hostRoot))
|
|
92443
93033
|
return hostRoot;
|
|
@@ -92900,7 +93490,7 @@ function provisionActiveLinkMirror(payload) {
|
|
|
92900
93490
|
if (!isInsideRoot(localRoot, HOST_ROOT))
|
|
92901
93491
|
return;
|
|
92902
93492
|
try {
|
|
92903
|
-
|
|
93493
|
+
mkdirSync27(localRoot, { recursive: true });
|
|
92904
93494
|
} catch {
|
|
92905
93495
|
}
|
|
92906
93496
|
saveLinkConfig({
|
|
@@ -93325,12 +93915,12 @@ async function serveInboundTerm(p, driverClientId) {
|
|
|
93325
93915
|
const route2 = driverClientId ? { clientId: driverClientId } : {};
|
|
93326
93916
|
switch (p.type) {
|
|
93327
93917
|
case "term:open": {
|
|
93328
|
-
const
|
|
93918
|
+
const sink2 = {
|
|
93329
93919
|
output: (ptyId, base643) => send3("term", { type: "term:output", ptyId, base64: base643 }, route2),
|
|
93330
93920
|
exit: (ptyId, exitCode, signal) => send3("term", { type: "term:exit", ptyId, exitCode, signal }, route2)
|
|
93331
93921
|
};
|
|
93332
93922
|
try {
|
|
93333
|
-
const { pid } = await openPty({ ptyId: p.ptyId, clientId: driverClientId, shell: p.shell, args: p.args, cwd: p.cwd, cols: p.cols, rows: p.rows, env: p.env, hostRoot: HOST_CONTAIN },
|
|
93923
|
+
const { pid } = await openPty({ ptyId: p.ptyId, clientId: driverClientId, shell: p.shell, args: p.args, cwd: p.cwd, cols: p.cols, rows: p.rows, env: p.env, hostRoot: HOST_CONTAIN }, sink2);
|
|
93334
93924
|
send3("term", { type: "term:opened", ptyId: p.ptyId, requestId: p.requestId, pid }, route2);
|
|
93335
93925
|
} catch (err2) {
|
|
93336
93926
|
send3("term", { type: "term:openError", ptyId: p.ptyId, requestId: p.requestId, error: err2 instanceof Error ? err2.message : String(err2) }, route2);
|
|
@@ -95313,7 +95903,7 @@ function setInProcConnector(fn) {
|
|
|
95313
95903
|
|
|
95314
95904
|
// ../../packages/host-core/dist/rdesk/server-prefs.js
|
|
95315
95905
|
init_credentials();
|
|
95316
|
-
import { readFileSync as
|
|
95906
|
+
import { readFileSync as readFileSync37, writeFileSync as writeFileSync26 } from "node:fs";
|
|
95317
95907
|
import { join as join55 } from "node:path";
|
|
95318
95908
|
function rdeskServerPrefsPath() {
|
|
95319
95909
|
return join55(daemonDir2(), "rdesk-server.json");
|
|
@@ -95328,7 +95918,7 @@ var DEFAULTS2 = {
|
|
|
95328
95918
|
};
|
|
95329
95919
|
function readRdeskServerPrefs() {
|
|
95330
95920
|
try {
|
|
95331
|
-
const p = JSON.parse(
|
|
95921
|
+
const p = JSON.parse(readFileSync37(rdeskServerPrefsPath(), "utf8"));
|
|
95332
95922
|
return {
|
|
95333
95923
|
// `!== false` (not `?? true`): only an explicit opt-out disables sharing, so a
|
|
95334
95924
|
// partially-written or older prefs file never silently turns the machine off.
|
|
@@ -95361,7 +95951,7 @@ function rdeskSharingEnabled() {
|
|
|
95361
95951
|
// ../../packages/host-core/dist/rdesk/password.js
|
|
95362
95952
|
init_credentials();
|
|
95363
95953
|
import { scryptSync, randomBytes as randomBytes5, timingSafeEqual as timingSafeEqual4, randomInt } from "node:crypto";
|
|
95364
|
-
import { readFileSync as
|
|
95954
|
+
import { readFileSync as readFileSync38, writeFileSync as writeFileSync27, existsSync as existsSync26, unlinkSync as unlinkSync3 } from "node:fs";
|
|
95365
95955
|
import { join as join56 } from "node:path";
|
|
95366
95956
|
function pwFile() {
|
|
95367
95957
|
return join56(daemonDir2(), "rdesk-password.json");
|
|
@@ -95379,27 +95969,27 @@ function generatePassword() {
|
|
|
95379
95969
|
}
|
|
95380
95970
|
function writePlain(password) {
|
|
95381
95971
|
try {
|
|
95382
|
-
const
|
|
95383
|
-
if (!
|
|
95972
|
+
const safe2 = electronModule()?.safeStorage;
|
|
95973
|
+
if (!safe2?.isEncryptionAvailable())
|
|
95384
95974
|
return;
|
|
95385
|
-
writeFileSync27(pwPlainFile(),
|
|
95975
|
+
writeFileSync27(pwPlainFile(), safe2.encryptString(password), { mode: 384 });
|
|
95386
95976
|
} catch {
|
|
95387
95977
|
}
|
|
95388
95978
|
}
|
|
95389
95979
|
function canRevealRdeskPassword() {
|
|
95390
95980
|
try {
|
|
95391
|
-
const
|
|
95392
|
-
return !!
|
|
95981
|
+
const safe2 = electronModule()?.safeStorage;
|
|
95982
|
+
return !!safe2?.isEncryptionAvailable() && existsSync26(pwPlainFile());
|
|
95393
95983
|
} catch {
|
|
95394
95984
|
return false;
|
|
95395
95985
|
}
|
|
95396
95986
|
}
|
|
95397
95987
|
function readRdeskPasswordPlain() {
|
|
95398
95988
|
try {
|
|
95399
|
-
const
|
|
95400
|
-
if (!
|
|
95989
|
+
const safe2 = electronModule()?.safeStorage;
|
|
95990
|
+
if (!safe2?.isEncryptionAvailable())
|
|
95401
95991
|
return null;
|
|
95402
|
-
return
|
|
95992
|
+
return safe2.decryptString(readFileSync38(pwPlainFile()));
|
|
95403
95993
|
} catch {
|
|
95404
95994
|
return null;
|
|
95405
95995
|
}
|
|
@@ -95432,7 +96022,7 @@ function ensureRdeskPassword() {
|
|
|
95432
96022
|
return regenerateRdeskPassword();
|
|
95433
96023
|
}
|
|
95434
96024
|
function hasRdeskPassword() {
|
|
95435
|
-
return !!process.env.CCB_RDESK_PASSWORD ||
|
|
96025
|
+
return !!process.env.CCB_RDESK_PASSWORD || existsSync26(pwFile());
|
|
95436
96026
|
}
|
|
95437
96027
|
function verifyRdeskPassword(password) {
|
|
95438
96028
|
if (!password)
|
|
@@ -95441,7 +96031,7 @@ function verifyRdeskPassword(password) {
|
|
|
95441
96031
|
if (override)
|
|
95442
96032
|
return password.length === override.length && timingSafeEqual4(Buffer.from(password), Buffer.from(override));
|
|
95443
96033
|
try {
|
|
95444
|
-
const { salt, hash: hash2 } = JSON.parse(
|
|
96034
|
+
const { salt, hash: hash2 } = JSON.parse(readFileSync38(pwFile(), "utf8"));
|
|
95445
96035
|
const got = scryptSync(password, Buffer.from(salt, "hex"), 32);
|
|
95446
96036
|
const want = Buffer.from(hash2, "hex");
|
|
95447
96037
|
return got.length === want.length && timingSafeEqual4(got, want);
|
|
@@ -96007,8 +96597,8 @@ function createPasskeyRegistration(rpId) {
|
|
|
96007
96597
|
|
|
96008
96598
|
// ../../packages/host-core/dist/vault/manager.js
|
|
96009
96599
|
init_base_paths();
|
|
96010
|
-
import { mkdirSync as
|
|
96011
|
-
import { dirname as
|
|
96600
|
+
import { mkdirSync as mkdirSync30, readFileSync as readFileSync41, writeFileSync as writeFileSync30 } from "node:fs";
|
|
96601
|
+
import { dirname as dirname24 } from "node:path";
|
|
96012
96602
|
|
|
96013
96603
|
// ../../packages/vault-core/dist/crypto.js
|
|
96014
96604
|
init_argon2();
|
|
@@ -97032,8 +97622,8 @@ function makeDaemonVaultApi(getOrigin, getToken2) {
|
|
|
97032
97622
|
|
|
97033
97623
|
// ../../packages/host-core/dist/vault/persistence.js
|
|
97034
97624
|
init_base_paths();
|
|
97035
|
-
import { existsSync as
|
|
97036
|
-
import { dirname as
|
|
97625
|
+
import { existsSync as existsSync27, mkdirSync as mkdirSync28, readFileSync as readFileSync39, writeFileSync as writeFileSync28, unlinkSync as unlinkSync4 } from "node:fs";
|
|
97626
|
+
import { dirname as dirname23 } from "node:path";
|
|
97037
97627
|
function vaultStoreFile() {
|
|
97038
97628
|
return homePath(".tesseract", "vault", "vault.json");
|
|
97039
97629
|
}
|
|
@@ -97044,9 +97634,9 @@ function makeVaultPersistence(file2 = vaultStoreFile, deviceKeyFile = vaultDevic
|
|
|
97044
97634
|
return {
|
|
97045
97635
|
load() {
|
|
97046
97636
|
try {
|
|
97047
|
-
if (!
|
|
97637
|
+
if (!existsSync27(file2()))
|
|
97048
97638
|
return null;
|
|
97049
|
-
const parsed = JSON.parse(
|
|
97639
|
+
const parsed = JSON.parse(readFileSync39(file2(), "utf8"));
|
|
97050
97640
|
if (!parsed || typeof parsed !== "object")
|
|
97051
97641
|
return null;
|
|
97052
97642
|
return { meta: parsed.meta ?? null, items: Array.isArray(parsed.items) ? parsed.items : [] };
|
|
@@ -97056,28 +97646,28 @@ function makeVaultPersistence(file2 = vaultStoreFile, deviceKeyFile = vaultDevic
|
|
|
97056
97646
|
},
|
|
97057
97647
|
save(state3) {
|
|
97058
97648
|
try {
|
|
97059
|
-
|
|
97649
|
+
mkdirSync28(dirname23(file2()), { recursive: true, mode: 448 });
|
|
97060
97650
|
writeFileSync28(file2(), JSON.stringify(state3), { mode: 384 });
|
|
97061
97651
|
} catch {
|
|
97062
97652
|
}
|
|
97063
97653
|
},
|
|
97064
97654
|
loadDeviceKey() {
|
|
97065
97655
|
try {
|
|
97066
|
-
return
|
|
97656
|
+
return existsSync27(deviceKeyFile()) ? readFileSync39(deviceKeyFile(), "utf8").trim() || null : null;
|
|
97067
97657
|
} catch {
|
|
97068
97658
|
return null;
|
|
97069
97659
|
}
|
|
97070
97660
|
},
|
|
97071
97661
|
saveDeviceKey(base64Key) {
|
|
97072
97662
|
try {
|
|
97073
|
-
|
|
97663
|
+
mkdirSync28(dirname23(deviceKeyFile()), { recursive: true, mode: 448 });
|
|
97074
97664
|
writeFileSync28(deviceKeyFile(), base64Key, { mode: 384 });
|
|
97075
97665
|
} catch {
|
|
97076
97666
|
}
|
|
97077
97667
|
},
|
|
97078
97668
|
clearDeviceKey() {
|
|
97079
97669
|
try {
|
|
97080
|
-
if (
|
|
97670
|
+
if (existsSync27(deviceKeyFile()))
|
|
97081
97671
|
unlinkSync4(deviceKeyFile());
|
|
97082
97672
|
} catch {
|
|
97083
97673
|
}
|
|
@@ -97087,7 +97677,7 @@ function makeVaultPersistence(file2 = vaultStoreFile, deviceKeyFile = vaultDevic
|
|
|
97087
97677
|
|
|
97088
97678
|
// ../../packages/host-core/dist/vault/biometric.js
|
|
97089
97679
|
init_base_paths();
|
|
97090
|
-
import { existsSync as
|
|
97680
|
+
import { existsSync as existsSync28, mkdirSync as mkdirSync29, readFileSync as readFileSync40, rmSync as rmSync6, writeFileSync as writeFileSync29 } from "node:fs";
|
|
97091
97681
|
import { join as join57 } from "node:path";
|
|
97092
97682
|
async function electronBio() {
|
|
97093
97683
|
if (!electronModule())
|
|
@@ -97105,7 +97695,7 @@ async function electronBio() {
|
|
|
97105
97695
|
}
|
|
97106
97696
|
function bioDir() {
|
|
97107
97697
|
const d = homePath(".tesseract", "vault-bio");
|
|
97108
|
-
|
|
97698
|
+
mkdirSync29(d, { recursive: true, mode: 448 });
|
|
97109
97699
|
return d;
|
|
97110
97700
|
}
|
|
97111
97701
|
function bioFile(id) {
|
|
@@ -97124,7 +97714,7 @@ async function biometricAvailable() {
|
|
|
97124
97714
|
}
|
|
97125
97715
|
}
|
|
97126
97716
|
function biometricEnrolled(id) {
|
|
97127
|
-
return
|
|
97717
|
+
return existsSync28(bioFile(id));
|
|
97128
97718
|
}
|
|
97129
97719
|
async function biometricEnroll(id, base64Key) {
|
|
97130
97720
|
const bio = await electronBio();
|
|
@@ -97135,13 +97725,13 @@ async function biometricEnroll(id, base64Key) {
|
|
|
97135
97725
|
}
|
|
97136
97726
|
async function biometricUnlock(id) {
|
|
97137
97727
|
const f = bioFile(id);
|
|
97138
|
-
if (!
|
|
97728
|
+
if (!existsSync28(f))
|
|
97139
97729
|
throw new Error("Touch ID is not set up for this vault.");
|
|
97140
97730
|
const bio = await electronBio();
|
|
97141
97731
|
if (!bio)
|
|
97142
97732
|
throw new Error("Touch ID is not available on this device.");
|
|
97143
97733
|
await bio.systemPreferences.promptTouchID("unlock your vault");
|
|
97144
|
-
return bio.safeStorage.decryptString(
|
|
97734
|
+
return bio.safeStorage.decryptString(readFileSync40(f));
|
|
97145
97735
|
}
|
|
97146
97736
|
function biometricDisable(id) {
|
|
97147
97737
|
try {
|
|
@@ -97171,7 +97761,7 @@ var VaultManager = class {
|
|
|
97171
97761
|
// ── auto-lock ────────────────────────────────────────────────────────────────────
|
|
97172
97762
|
loadAutoLock() {
|
|
97173
97763
|
try {
|
|
97174
|
-
const raw = JSON.parse(
|
|
97764
|
+
const raw = JSON.parse(readFileSync41(settingsFile(), "utf8"));
|
|
97175
97765
|
return Number.isFinite(raw.autoLockMinutes) ? Math.max(0, raw.autoLockMinutes) : 0;
|
|
97176
97766
|
} catch {
|
|
97177
97767
|
return 0;
|
|
@@ -97179,7 +97769,7 @@ var VaultManager = class {
|
|
|
97179
97769
|
}
|
|
97180
97770
|
saveAutoLock() {
|
|
97181
97771
|
try {
|
|
97182
|
-
|
|
97772
|
+
mkdirSync30(dirname24(settingsFile()), { recursive: true, mode: 448 });
|
|
97183
97773
|
writeFileSync30(settingsFile(), JSON.stringify({ autoLockMinutes: this.autoLockMinutes }), { mode: 384 });
|
|
97184
97774
|
} catch {
|
|
97185
97775
|
}
|
|
@@ -98218,7 +98808,7 @@ async function startLocalServer(opts) {
|
|
|
98218
98808
|
|
|
98219
98809
|
// ../../packages/host-core/dist/daemon-runtime.js
|
|
98220
98810
|
init_base_paths();
|
|
98221
|
-
import { readFileSync as
|
|
98811
|
+
import { readFileSync as readFileSync46, writeFileSync as writeFileSync38, existsSync as existsSync36, mkdirSync as mkdirSync38, unlinkSync as unlinkSync6, chmodSync as chmodSync7, statSync as statSync10 } from "node:fs";
|
|
98222
98812
|
import { execFileSync as execFileSync5 } from "node:child_process";
|
|
98223
98813
|
import { join as join70 } from "node:path";
|
|
98224
98814
|
import { randomBytes as randomBytes10 } from "node:crypto";
|
|
@@ -98227,7 +98817,7 @@ import { hostname as hostname5 } from "node:os";
|
|
|
98227
98817
|
// ../../packages/shared/dist/daemon-registry.js
|
|
98228
98818
|
init_base_paths();
|
|
98229
98819
|
import { execFileSync as execFileSync3 } from "node:child_process";
|
|
98230
|
-
import { existsSync as
|
|
98820
|
+
import { existsSync as existsSync29, mkdirSync as mkdirSync31, readdirSync as readdirSync9, readFileSync as readFileSync42, readlinkSync, unlinkSync as unlinkSync5, writeFileSync as writeFileSync31 } from "node:fs";
|
|
98231
98821
|
import { join as join58 } from "node:path";
|
|
98232
98822
|
var SUPERVISOR_PID = Number(process.env.CCB_DAEMON_SUPERVISOR_PID ?? 0) || 0;
|
|
98233
98823
|
delete process.env.CCB_DAEMON_SUPERVISOR_PID;
|
|
@@ -98323,7 +98913,7 @@ function pidStillMatches(pid, rec) {
|
|
|
98323
98913
|
}
|
|
98324
98914
|
function registerSelfAsDaemon(version2) {
|
|
98325
98915
|
try {
|
|
98326
|
-
|
|
98916
|
+
mkdirSync31(registryDir(), { recursive: true, mode: 448 });
|
|
98327
98917
|
const rec = {
|
|
98328
98918
|
pid: process.pid,
|
|
98329
98919
|
startedAt: procStartedAt(process.pid),
|
|
@@ -98352,7 +98942,7 @@ function unregisterSelfAsDaemon() {
|
|
|
98352
98942
|
}
|
|
98353
98943
|
function readRecord(pid) {
|
|
98354
98944
|
try {
|
|
98355
|
-
return JSON.parse(
|
|
98945
|
+
return JSON.parse(readFileSync42(recordPath(pid), "utf-8"));
|
|
98356
98946
|
} catch {
|
|
98357
98947
|
return null;
|
|
98358
98948
|
}
|
|
@@ -98366,7 +98956,7 @@ function allRegisteredPids() {
|
|
|
98366
98956
|
}
|
|
98367
98957
|
function registeredDaemons(selfPid) {
|
|
98368
98958
|
const out = [];
|
|
98369
|
-
if (!
|
|
98959
|
+
if (!existsSync29(registryDir()))
|
|
98370
98960
|
return out;
|
|
98371
98961
|
for (const pid of allRegisteredPids()) {
|
|
98372
98962
|
if (pid === selfPid)
|
|
@@ -98458,7 +99048,7 @@ function liveDaemons() {
|
|
|
98458
99048
|
|
|
98459
99049
|
// ../../packages/host-core/dist/device-identity.js
|
|
98460
99050
|
import { join as join59 } from "node:path";
|
|
98461
|
-
import { readFileSync as
|
|
99051
|
+
import { readFileSync as readFileSync43, writeFileSync as writeFileSync32, existsSync as existsSync30, mkdirSync as mkdirSync32, renameSync as renameSync10, chmodSync as chmodSync4 } from "node:fs";
|
|
98462
99052
|
init_credentials();
|
|
98463
99053
|
var cached2 = null;
|
|
98464
99054
|
function identityPath() {
|
|
@@ -98468,7 +99058,7 @@ async function loadOrCreateDeviceIdentity() {
|
|
|
98468
99058
|
if (cached2)
|
|
98469
99059
|
return cached2;
|
|
98470
99060
|
try {
|
|
98471
|
-
const stored = JSON.parse(
|
|
99061
|
+
const stored = JSON.parse(readFileSync43(identityPath(), "utf-8"));
|
|
98472
99062
|
if (stored?.privateJwk) {
|
|
98473
99063
|
cached2 = await importIdentity(stored.privateJwk);
|
|
98474
99064
|
return cached2;
|
|
@@ -98478,11 +99068,11 @@ async function loadOrCreateDeviceIdentity() {
|
|
|
98478
99068
|
const kp = await generateIdentityKeyPair(true);
|
|
98479
99069
|
const { privateJwk, publicRaw } = await exportIdentity(kp);
|
|
98480
99070
|
const dir2 = daemonDir2();
|
|
98481
|
-
if (!
|
|
98482
|
-
|
|
99071
|
+
if (!existsSync30(dir2))
|
|
99072
|
+
mkdirSync32(dir2, { recursive: true, mode: 448 });
|
|
98483
99073
|
const tmp = `${identityPath()}.tmp`;
|
|
98484
99074
|
writeFileSync32(tmp, JSON.stringify({ privateJwk, publicRaw, alg: "P256-ECDSA" }, null, 2), { mode: 384 });
|
|
98485
|
-
|
|
99075
|
+
renameSync10(tmp, identityPath());
|
|
98486
99076
|
try {
|
|
98487
99077
|
chmodSync4(identityPath(), 384);
|
|
98488
99078
|
} catch {
|
|
@@ -98500,7 +99090,7 @@ async function loadOrCreateSealingKey() {
|
|
|
98500
99090
|
return sealingCached;
|
|
98501
99091
|
const { subtle: subtle5 } = globalThis.crypto;
|
|
98502
99092
|
try {
|
|
98503
|
-
const stored = JSON.parse(
|
|
99093
|
+
const stored = JSON.parse(readFileSync43(sealingPath(), "utf-8"));
|
|
98504
99094
|
if (stored?.privateJwk && stored.publicRaw) {
|
|
98505
99095
|
const privateKey = await subtle5.importKey("jwk", stored.privateJwk, EC_DH, true, ["deriveBits"]);
|
|
98506
99096
|
sealingCached = { privateKey, publicRaw: unb64u(stored.publicRaw) };
|
|
@@ -98512,11 +99102,11 @@ async function loadOrCreateSealingKey() {
|
|
|
98512
99102
|
const publicRaw = new Uint8Array(await subtle5.exportKey("raw", kp.publicKey));
|
|
98513
99103
|
const privateJwk = await subtle5.exportKey("jwk", kp.privateKey);
|
|
98514
99104
|
const dir2 = daemonDir2();
|
|
98515
|
-
if (!
|
|
98516
|
-
|
|
99105
|
+
if (!existsSync30(dir2))
|
|
99106
|
+
mkdirSync32(dir2, { recursive: true, mode: 448 });
|
|
98517
99107
|
const tmp = `${sealingPath()}.tmp`;
|
|
98518
99108
|
writeFileSync32(tmp, JSON.stringify({ privateJwk, publicRaw: b64u(publicRaw), alg: "P256-ECDH" }, null, 2), { mode: 384 });
|
|
98519
|
-
|
|
99109
|
+
renameSync10(tmp, sealingPath());
|
|
98520
99110
|
try {
|
|
98521
99111
|
chmodSync4(sealingPath(), 384);
|
|
98522
99112
|
} catch {
|
|
@@ -98579,8 +99169,8 @@ import { createRequire as createRequire4 } from "node:module";
|
|
|
98579
99169
|
|
|
98580
99170
|
// ../../packages/host-core/dist/mesh/config.js
|
|
98581
99171
|
init_credentials();
|
|
98582
|
-
import { chmodSync as chmodSync5, existsSync as
|
|
98583
|
-
import { dirname as
|
|
99172
|
+
import { chmodSync as chmodSync5, existsSync as existsSync31, mkdirSync as mkdirSync33, readdirSync as readdirSync10, readFileSync as readFileSync44, renameSync as renameSync11, rmSync as rmSync7, writeFileSync as writeFileSync33 } from "node:fs";
|
|
99173
|
+
import { dirname as dirname25, join as join60 } from "node:path";
|
|
98584
99174
|
function meshDir() {
|
|
98585
99175
|
return join60(daemonDir2(), "mesh");
|
|
98586
99176
|
}
|
|
@@ -98623,27 +99213,27 @@ var FILES = {
|
|
|
98623
99213
|
function readIfPresent(name, dir2 = meshDir()) {
|
|
98624
99214
|
const p = join60(dir2, name);
|
|
98625
99215
|
try {
|
|
98626
|
-
return
|
|
99216
|
+
return existsSync31(p) ? new Uint8Array(readFileSync44(p)) : void 0;
|
|
98627
99217
|
} catch {
|
|
98628
99218
|
return void 0;
|
|
98629
99219
|
}
|
|
98630
99220
|
}
|
|
98631
99221
|
function migrateSingleMesh() {
|
|
98632
99222
|
const legacyGenesis = join60(meshDir(), FILES.genesis);
|
|
98633
|
-
if (!
|
|
99223
|
+
if (!existsSync31(legacyGenesis))
|
|
98634
99224
|
return null;
|
|
98635
99225
|
const id = meshIdFromCert(readIfPresent(FILES.cert)) ?? LEGACY_MESH_ID;
|
|
98636
99226
|
const dest = oneMeshDir(id);
|
|
98637
99227
|
try {
|
|
98638
|
-
|
|
99228
|
+
mkdirSync33(dest, { recursive: true, mode: 448 });
|
|
98639
99229
|
chmodSync5(dest, 448);
|
|
98640
99230
|
for (const f of Object.values(FILES)) {
|
|
98641
99231
|
const from = join60(meshDir(), f);
|
|
98642
|
-
if (
|
|
98643
|
-
|
|
99232
|
+
if (existsSync31(from))
|
|
99233
|
+
renameSync11(from, join60(dest, f));
|
|
98644
99234
|
}
|
|
98645
99235
|
const key2 = join60(dest, FILES.key);
|
|
98646
|
-
if (
|
|
99236
|
+
if (existsSync31(key2))
|
|
98647
99237
|
chmodSync5(key2, 384);
|
|
98648
99238
|
} catch {
|
|
98649
99239
|
return null;
|
|
@@ -98666,14 +99256,14 @@ function listMeshIds() {
|
|
|
98666
99256
|
}
|
|
98667
99257
|
function readLocal(meshId) {
|
|
98668
99258
|
try {
|
|
98669
|
-
return JSON.parse(
|
|
99259
|
+
return JSON.parse(readFileSync44(join60(oneMeshDir(meshId), FILES.local), "utf8"));
|
|
98670
99260
|
} catch {
|
|
98671
99261
|
return null;
|
|
98672
99262
|
}
|
|
98673
99263
|
}
|
|
98674
99264
|
function writeLocal(meshId, state3) {
|
|
98675
99265
|
try {
|
|
98676
|
-
|
|
99266
|
+
mkdirSync33(oneMeshDir(meshId), { recursive: true, mode: 448 });
|
|
98677
99267
|
writeFileSync33(join60(oneMeshDir(meshId), FILES.local), JSON.stringify(state3, null, 2), { mode: 384 });
|
|
98678
99268
|
} catch {
|
|
98679
99269
|
}
|
|
@@ -98720,7 +99310,7 @@ function saveMeshIdentity(id) {
|
|
|
98720
99310
|
saveMesh(meshId, id);
|
|
98721
99311
|
return;
|
|
98722
99312
|
}
|
|
98723
|
-
|
|
99313
|
+
mkdirSync33(meshDir(), { recursive: true, mode: 448 });
|
|
98724
99314
|
try {
|
|
98725
99315
|
chmodSync5(meshDir(), 448);
|
|
98726
99316
|
} catch {
|
|
@@ -98733,7 +99323,7 @@ function saveMeshIdentity(id) {
|
|
|
98733
99323
|
}
|
|
98734
99324
|
function saveMesh(meshId, id) {
|
|
98735
99325
|
const dir2 = oneMeshDir(meshId);
|
|
98736
|
-
|
|
99326
|
+
mkdirSync33(dir2, { recursive: true, mode: 448 });
|
|
98737
99327
|
try {
|
|
98738
99328
|
chmodSync5(meshDir(), 448);
|
|
98739
99329
|
} catch {
|
|
@@ -98767,7 +99357,7 @@ function statusPath(meshId) {
|
|
|
98767
99357
|
function writeStatus(status2, meshId) {
|
|
98768
99358
|
try {
|
|
98769
99359
|
const p = statusPath(meshId);
|
|
98770
|
-
|
|
99360
|
+
mkdirSync33(dirname25(p), { recursive: true, mode: 448 });
|
|
98771
99361
|
writeFileSync33(p, JSON.stringify({ ...status2, at: Date.now() }, null, 2));
|
|
98772
99362
|
} catch {
|
|
98773
99363
|
}
|
|
@@ -98780,7 +99370,7 @@ function clearStatus(meshId) {
|
|
|
98780
99370
|
}
|
|
98781
99371
|
function readStatus(meshId) {
|
|
98782
99372
|
try {
|
|
98783
|
-
const raw = JSON.parse(
|
|
99373
|
+
const raw = JSON.parse(readFileSync44(statusPath(meshId), "utf8"));
|
|
98784
99374
|
if (typeof raw.at !== "number")
|
|
98785
99375
|
return null;
|
|
98786
99376
|
return { ...raw, at: raw.at, stale: Date.now() - raw.at > STATUS_STALE_MS };
|
|
@@ -98792,7 +99382,7 @@ function cacheBundle(bundle, meshId) {
|
|
|
98792
99382
|
try {
|
|
98793
99383
|
const id = meshId ?? listMeshIds()[0];
|
|
98794
99384
|
const dir2 = id === void 0 ? meshDir() : oneMeshDir(id);
|
|
98795
|
-
|
|
99385
|
+
mkdirSync33(dir2, { recursive: true, mode: 448 });
|
|
98796
99386
|
writeFileSync33(join60(dir2, FILES.bundle), bundle);
|
|
98797
99387
|
} catch {
|
|
98798
99388
|
}
|
|
@@ -99845,7 +100435,7 @@ function startNodes(log9) {
|
|
|
99845
100435
|
}
|
|
99846
100436
|
|
|
99847
100437
|
// ../../packages/host-core/dist/drops/receive-ui.js
|
|
99848
|
-
import { basename as basename12, dirname as
|
|
100438
|
+
import { basename as basename12, dirname as dirname26 } from "node:path";
|
|
99849
100439
|
var log5 = (...a) => console.log("[drops]", ...a);
|
|
99850
100440
|
function formatBytes(n) {
|
|
99851
100441
|
if (!Number.isFinite(n) || n <= 0)
|
|
@@ -100187,7 +100777,7 @@ function createDropHandler(deps) {
|
|
|
100187
100777
|
// ../../packages/host-core/dist/drops/blob-fetch.js
|
|
100188
100778
|
import { createWriteStream as createWriteStream2 } from "node:fs";
|
|
100189
100779
|
import { mkdir as mkdir13, rm as rm5, chmod as chmod3 } from "node:fs/promises";
|
|
100190
|
-
import { dirname as
|
|
100780
|
+
import { dirname as dirname27, join as join63 } from "node:path";
|
|
100191
100781
|
import { Readable as Readable2 } from "node:stream";
|
|
100192
100782
|
import { pipeline } from "node:stream/promises";
|
|
100193
100783
|
|
|
@@ -100385,7 +100975,7 @@ async function fetchBlobDrop(opts) {
|
|
|
100385
100975
|
log7(`drop ${opts.dropId}: refusing a path outside the destination`);
|
|
100386
100976
|
continue;
|
|
100387
100977
|
}
|
|
100388
|
-
await mkdir13(
|
|
100978
|
+
await mkdir13(dirname27(abs), { recursive: true });
|
|
100389
100979
|
abs = await uniqueDropPath(abs);
|
|
100390
100980
|
const res = await fetchFn(new URL(item.url, opts.apiOrigin).toString(), { signal: opts.signal });
|
|
100391
100981
|
if (!res.ok || !res.body)
|
|
@@ -100657,13 +101247,13 @@ var RdeskServerChannel = class {
|
|
|
100657
101247
|
};
|
|
100658
101248
|
|
|
100659
101249
|
// ../../packages/host-core/dist/rdesk/channel-client.js
|
|
100660
|
-
import { readFileSync as
|
|
101250
|
+
import { readFileSync as readFileSync45 } from "node:fs";
|
|
100661
101251
|
import { join as join64 } from "node:path";
|
|
100662
101252
|
var RECONNECT_MS = 2e3;
|
|
100663
101253
|
var CLAIM_RETRY_MS = 5e3;
|
|
100664
101254
|
function readEndpoint(dir2, selfPid) {
|
|
100665
101255
|
try {
|
|
100666
|
-
const s = JSON.parse(
|
|
101256
|
+
const s = JSON.parse(readFileSync45(join64(dir2, "status.json"), "utf8"));
|
|
100667
101257
|
if (selfPid && s.pid === selfPid)
|
|
100668
101258
|
return null;
|
|
100669
101259
|
return s.localPort && s.localToken ? `ws://127.0.0.1:${s.localPort}/?token=${s.localToken}` : null;
|
|
@@ -101097,16 +101687,16 @@ function registerRdpEngine() {
|
|
|
101097
101687
|
init_credentials();
|
|
101098
101688
|
import { appendFile, stat as stat8, rename as rename3 } from "node:fs/promises";
|
|
101099
101689
|
import { join as join65 } from "node:path";
|
|
101100
|
-
var
|
|
101690
|
+
var MAX_BYTES2 = 2 * 1024 * 1024;
|
|
101101
101691
|
function rdeskAuditPath() {
|
|
101102
101692
|
return join65(daemonDir2(), "rdesk-audit.jsonl");
|
|
101103
101693
|
}
|
|
101104
101694
|
var queue = [];
|
|
101105
101695
|
var draining = false;
|
|
101106
|
-
async function
|
|
101696
|
+
async function rotateIfNeeded2(path6) {
|
|
101107
101697
|
try {
|
|
101108
101698
|
const st = await stat8(path6);
|
|
101109
|
-
if (st.size <
|
|
101699
|
+
if (st.size < MAX_BYTES2)
|
|
101110
101700
|
return;
|
|
101111
101701
|
await rename3(path6, `${path6}.1`);
|
|
101112
101702
|
} catch {
|
|
@@ -101121,7 +101711,7 @@ async function drain() {
|
|
|
101121
101711
|
const batch = queue.join("");
|
|
101122
101712
|
queue = [];
|
|
101123
101713
|
const path6 = rdeskAuditPath();
|
|
101124
|
-
await
|
|
101714
|
+
await rotateIfNeeded2(path6);
|
|
101125
101715
|
await appendFile(path6, batch, { mode: 384 });
|
|
101126
101716
|
}
|
|
101127
101717
|
} catch {
|
|
@@ -101140,7 +101730,7 @@ function appendRdeskAudit(e) {
|
|
|
101140
101730
|
}
|
|
101141
101731
|
|
|
101142
101732
|
// ../../packages/host-core/dist/fileprovider-bridge.js
|
|
101143
|
-
import { writeFileSync as writeFileSync34, mkdirSync as
|
|
101733
|
+
import { writeFileSync as writeFileSync34, mkdirSync as mkdirSync34, rmSync as rmSync8, existsSync as existsSync32 } from "node:fs";
|
|
101144
101734
|
import { homedir as homedir9 } from "node:os";
|
|
101145
101735
|
import { join as join66 } from "node:path";
|
|
101146
101736
|
var APPEX_BUNDLE_ID = "dev.tesseract.FileProvider";
|
|
@@ -101313,7 +101903,7 @@ function stopFileProviderBridge() {
|
|
|
101313
101903
|
|
|
101314
101904
|
// ../../packages/host-core/dist/vault/autofill-bridge.js
|
|
101315
101905
|
import { randomBytes as randomBytes9 } from "node:crypto";
|
|
101316
|
-
import { existsSync as
|
|
101906
|
+
import { existsSync as existsSync33, mkdirSync as mkdirSync35, writeFileSync as writeFileSync35, rmSync as rmSync9 } from "node:fs";
|
|
101317
101907
|
import { homedir as homedir10 } from "node:os";
|
|
101318
101908
|
import { join as join67 } from "node:path";
|
|
101319
101909
|
|
|
@@ -101388,7 +101978,7 @@ function writeBridgeInfo(port, token3, log9) {
|
|
|
101388
101978
|
return;
|
|
101389
101979
|
const containerData = appexContainerData();
|
|
101390
101980
|
try {
|
|
101391
|
-
if (!
|
|
101981
|
+
if (!existsSync33(containerData)) {
|
|
101392
101982
|
if (!infoLoggedOnce) {
|
|
101393
101983
|
infoLoggedOnce = true;
|
|
101394
101984
|
log9("autofill bridge-info SKIP: no appex container yet at", containerData);
|
|
@@ -101396,7 +101986,7 @@ function writeBridgeInfo(port, token3, log9) {
|
|
|
101396
101986
|
return;
|
|
101397
101987
|
}
|
|
101398
101988
|
const dir2 = join67(containerData, "Library", "Application Support");
|
|
101399
|
-
|
|
101989
|
+
mkdirSync35(dir2, { recursive: true });
|
|
101400
101990
|
writeFileSync35(bridgeInfoPath(), JSON.stringify({ port, token: token3, pid: process.pid, ts: Date.now() }), { mode: 384 });
|
|
101401
101991
|
if (!infoLoggedOnce) {
|
|
101402
101992
|
infoLoggedOnce = true;
|
|
@@ -101639,9 +102229,9 @@ function createNodePowerController() {
|
|
|
101639
102229
|
|
|
101640
102230
|
// ../../packages/host-core/dist/native-host.js
|
|
101641
102231
|
import { execFileSync as execFileSync4 } from "node:child_process";
|
|
101642
|
-
import { chmodSync as chmodSync6, existsSync as
|
|
102232
|
+
import { chmodSync as chmodSync6, existsSync as existsSync34, mkdirSync as mkdirSync36, writeFileSync as writeFileSync36 } from "node:fs";
|
|
101643
102233
|
import { homedir as homedir11, platform as platform5 } from "node:os";
|
|
101644
|
-
import { dirname as
|
|
102234
|
+
import { dirname as dirname28, join as join68, resolve as resolve12 } from "node:path";
|
|
101645
102235
|
import { fileURLToPath as fileURLToPath5 } from "node:url";
|
|
101646
102236
|
var HOST_NAME = "com.tesseract.companion";
|
|
101647
102237
|
var EXTENSION_IDS = ["icpnghhpcmaonjckkpilpajblfehpplo", "giolfpookdhjfafcchaflhmigghaeffn"];
|
|
@@ -101664,13 +102254,13 @@ function resolveBridge(log9) {
|
|
|
101664
102254
|
process.resourcesPath ? join68(process.resourcesPath, "companion-host", BRIDGE_BASENAME) : void 0
|
|
101665
102255
|
];
|
|
101666
102256
|
try {
|
|
101667
|
-
const here =
|
|
102257
|
+
const here = dirname28(fileURLToPath5(import.meta.url));
|
|
101668
102258
|
candidates.push(resolve12(here, "../../../apps/companion-host/dist", BRIDGE_BASENAME));
|
|
101669
102259
|
candidates.push(resolve12(here, "../../apps/companion-host/dist", BRIDGE_BASENAME));
|
|
101670
102260
|
} catch {
|
|
101671
102261
|
}
|
|
101672
102262
|
for (const c of candidates)
|
|
101673
|
-
if (c &&
|
|
102263
|
+
if (c && existsSync34(c))
|
|
101674
102264
|
return c;
|
|
101675
102265
|
log9("companion native-host: bridge not found; skipping registration (looked in", candidates.filter(Boolean).join(" , "), ")");
|
|
101676
102266
|
return null;
|
|
@@ -101699,7 +102289,7 @@ function registerNativeHost(opts) {
|
|
|
101699
102289
|
if (!bridge)
|
|
101700
102290
|
return;
|
|
101701
102291
|
const runtime = opts.runtime ?? process.execPath;
|
|
101702
|
-
|
|
102292
|
+
mkdirSync36(opts.daemonDir, { recursive: true });
|
|
101703
102293
|
const launcher = writeLauncher(opts.daemonDir, bridge, runtime);
|
|
101704
102294
|
const manifestJson = JSON.stringify({
|
|
101705
102295
|
name: HOST_NAME,
|
|
@@ -101712,11 +102302,11 @@ function registerNativeHost(opts) {
|
|
|
101712
102302
|
return registerWindows(opts.daemonDir, manifestJson, log9);
|
|
101713
102303
|
let wrote = 0;
|
|
101714
102304
|
for (const profile of browserProfileDirs()) {
|
|
101715
|
-
if (!
|
|
102305
|
+
if (!existsSync34(profile))
|
|
101716
102306
|
continue;
|
|
101717
102307
|
try {
|
|
101718
102308
|
const dir2 = join68(profile, "NativeMessagingHosts");
|
|
101719
|
-
|
|
102309
|
+
mkdirSync36(dir2, { recursive: true });
|
|
101720
102310
|
writeFileSync36(join68(dir2, `${HOST_NAME}.json`), manifestJson);
|
|
101721
102311
|
wrote++;
|
|
101722
102312
|
} catch {
|
|
@@ -101748,7 +102338,7 @@ init_daemon_settings();
|
|
|
101748
102338
|
|
|
101749
102339
|
// ../../packages/host-core/dist/activity/activity-tracker.js
|
|
101750
102340
|
init_credentials();
|
|
101751
|
-
import { promises as fsp, writeFileSync as writeFileSync37, mkdirSync as
|
|
102341
|
+
import { promises as fsp, writeFileSync as writeFileSync37, mkdirSync as mkdirSync37, existsSync as existsSync35 } from "node:fs";
|
|
101752
102342
|
import { join as join69 } from "node:path";
|
|
101753
102343
|
function activityProfilePath() {
|
|
101754
102344
|
return join69(daemonDir2(), "activity-profile.json");
|
|
@@ -101826,7 +102416,7 @@ function createActivityTracker(opts = {}) {
|
|
|
101826
102416
|
return;
|
|
101827
102417
|
const key2 = front.bundleId || front.name;
|
|
101828
102418
|
await ensureLoaded();
|
|
101829
|
-
if (profile && Object.keys(profile.apps).length && !
|
|
102419
|
+
if (profile && Object.keys(profile.apps).length && !existsSync35(activityProfilePath())) {
|
|
101830
102420
|
log9("activity profile cleared externally \u2014 resetting in-memory");
|
|
101831
102421
|
profile = { version: 1, updatedAt: (/* @__PURE__ */ new Date()).toISOString(), apps: {} };
|
|
101832
102422
|
}
|
|
@@ -101862,7 +102452,7 @@ function createActivityTracker(opts = {}) {
|
|
|
101862
102452
|
if (profile) {
|
|
101863
102453
|
pruneProfile(profile);
|
|
101864
102454
|
profile.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
101865
|
-
|
|
102455
|
+
mkdirSync37(daemonDir2(), { recursive: true, mode: 448 });
|
|
101866
102456
|
writeFileSync37(activityProfilePath(), JSON.stringify(profile), { mode: 384 });
|
|
101867
102457
|
dirty = 0;
|
|
101868
102458
|
}
|
|
@@ -101933,13 +102523,21 @@ var reporting = false;
|
|
|
101933
102523
|
var surface = "daemon";
|
|
101934
102524
|
var logFn = () => {
|
|
101935
102525
|
};
|
|
101936
|
-
function endpoint() {
|
|
101937
|
-
const
|
|
101938
|
-
|
|
102526
|
+
function endpoint(apiOrigin) {
|
|
102527
|
+
const explicit = process.env.CCB_ERROR_ENDPOINT?.trim().replace(/\/$/, "");
|
|
102528
|
+
if (explicit)
|
|
102529
|
+
return `${explicit}/v1/reports`;
|
|
102530
|
+
const origin = apiOrigin?.trim().replace(/\/$/, "");
|
|
102531
|
+
return origin ? `${origin}/api/errors/v1/reports` : null;
|
|
101939
102532
|
}
|
|
101940
102533
|
function hasConsent() {
|
|
101941
102534
|
return process.env.CCB_CRASH_REPORT_CONSENT === "1";
|
|
101942
102535
|
}
|
|
102536
|
+
var LAUNCHER_SURFACES = /* @__PURE__ */ new Set(["daemon", "rdesk", "mesh"]);
|
|
102537
|
+
function surfaceFromEnv() {
|
|
102538
|
+
const s = process.env.CCB_ERROR_SURFACE?.trim();
|
|
102539
|
+
return s && LAUNCHER_SURFACES.has(s) ? s : "daemon";
|
|
102540
|
+
}
|
|
101943
102541
|
function initDaemonErrorReporter(opts = {}) {
|
|
101944
102542
|
if (timer)
|
|
101945
102543
|
return;
|
|
@@ -101990,16 +102588,16 @@ function captureDaemonError(error51, opts = {}) {
|
|
|
101990
102588
|
...opts.context ? { context: opts.context } : {},
|
|
101991
102589
|
fingerprint: ""
|
|
101992
102590
|
};
|
|
101993
|
-
const
|
|
101994
|
-
|
|
102591
|
+
const safe2 = redactError(report);
|
|
102592
|
+
safe2.fingerprint = computeFingerprint({
|
|
101995
102593
|
surface,
|
|
101996
|
-
type:
|
|
101997
|
-
message:
|
|
101998
|
-
stacktrace:
|
|
102594
|
+
type: safe2.exception.type,
|
|
102595
|
+
message: safe2.exception.message,
|
|
102596
|
+
stacktrace: safe2.exception.stacktrace
|
|
101999
102597
|
});
|
|
102000
102598
|
if (!hasConsent())
|
|
102001
102599
|
return;
|
|
102002
|
-
queue2.push(
|
|
102600
|
+
queue2.push(safe2);
|
|
102003
102601
|
if (queue2.length > MAX_QUEUE)
|
|
102004
102602
|
queue2.splice(0, queue2.length - MAX_QUEUE);
|
|
102005
102603
|
if (queue2.length >= 10)
|
|
@@ -102016,12 +102614,12 @@ async function flush2() {
|
|
|
102016
102614
|
return;
|
|
102017
102615
|
if (Date.now() < nextAttemptAt)
|
|
102018
102616
|
return;
|
|
102019
|
-
const url2 = endpoint();
|
|
102020
|
-
if (!url2)
|
|
102021
|
-
return;
|
|
102022
102617
|
const creds3 = readCredentials();
|
|
102023
102618
|
if (!creds3?.accessToken)
|
|
102024
102619
|
return;
|
|
102620
|
+
const url2 = endpoint(creds3.apiOrigin);
|
|
102621
|
+
if (!url2)
|
|
102622
|
+
return;
|
|
102025
102623
|
sending = true;
|
|
102026
102624
|
const batch = queue2.slice(0, 20);
|
|
102027
102625
|
try {
|
|
@@ -102072,7 +102670,7 @@ async function runDaemon(opts = {}) {
|
|
|
102072
102670
|
};
|
|
102073
102671
|
const lockHeldByAnother = () => {
|
|
102074
102672
|
try {
|
|
102075
|
-
const pid = Number(
|
|
102673
|
+
const pid = Number(readFileSync46(pidfile(), "utf-8").trim());
|
|
102076
102674
|
return Number.isFinite(pid) && pid > 0 && pid !== process.pid && isAlive2(pid);
|
|
102077
102675
|
} catch {
|
|
102078
102676
|
return false;
|
|
@@ -102081,8 +102679,8 @@ async function runDaemon(opts = {}) {
|
|
|
102081
102679
|
function acquireLock2() {
|
|
102082
102680
|
const f = pidfile();
|
|
102083
102681
|
try {
|
|
102084
|
-
if (!
|
|
102085
|
-
|
|
102682
|
+
if (!existsSync36(daemonDir2()))
|
|
102683
|
+
mkdirSync38(daemonDir2(), { recursive: true, mode: 448 });
|
|
102086
102684
|
} catch {
|
|
102087
102685
|
}
|
|
102088
102686
|
for (let attempt = 0; attempt < 2; attempt++) {
|
|
@@ -102091,7 +102689,7 @@ async function runDaemon(opts = {}) {
|
|
|
102091
102689
|
return true;
|
|
102092
102690
|
} catch {
|
|
102093
102691
|
try {
|
|
102094
|
-
const prev = Number(
|
|
102692
|
+
const prev = Number(readFileSync46(f, "utf-8").trim());
|
|
102095
102693
|
if (!prev)
|
|
102096
102694
|
return false;
|
|
102097
102695
|
if (prev !== process.pid && isAlive2(prev))
|
|
@@ -102107,7 +102705,7 @@ async function runDaemon(opts = {}) {
|
|
|
102107
102705
|
function releaseLock() {
|
|
102108
102706
|
try {
|
|
102109
102707
|
const f = pidfile();
|
|
102110
|
-
if (
|
|
102708
|
+
if (existsSync36(f) && Number(readFileSync46(f, "utf-8").trim()) === process.pid)
|
|
102111
102709
|
unlinkSync6(f);
|
|
102112
102710
|
} catch {
|
|
102113
102711
|
}
|
|
@@ -102117,11 +102715,11 @@ async function runDaemon(opts = {}) {
|
|
|
102117
102715
|
let lockPid = 0;
|
|
102118
102716
|
let status2 = {};
|
|
102119
102717
|
try {
|
|
102120
|
-
lockPid = Number(
|
|
102718
|
+
lockPid = Number(readFileSync46(pidfile(), "utf-8").trim());
|
|
102121
102719
|
} catch {
|
|
102122
102720
|
}
|
|
102123
102721
|
try {
|
|
102124
|
-
status2 = JSON.parse(
|
|
102722
|
+
status2 = JSON.parse(readFileSync46(statusFile(), "utf-8"));
|
|
102125
102723
|
} catch {
|
|
102126
102724
|
}
|
|
102127
102725
|
const statusPid = Number(status2.pid ?? 0);
|
|
@@ -102183,7 +102781,7 @@ async function runDaemon(opts = {}) {
|
|
|
102183
102781
|
forgetDaemon(p);
|
|
102184
102782
|
}
|
|
102185
102783
|
try {
|
|
102186
|
-
if (
|
|
102784
|
+
if (existsSync36(pidfile()))
|
|
102187
102785
|
unlinkSync6(pidfile());
|
|
102188
102786
|
} catch {
|
|
102189
102787
|
}
|
|
@@ -102392,7 +102990,7 @@ async function runDaemon(opts = {}) {
|
|
|
102392
102990
|
});
|
|
102393
102991
|
} catch {
|
|
102394
102992
|
}
|
|
102395
|
-
initDaemonErrorReporter({ surface:
|
|
102993
|
+
initDaemonErrorReporter({ surface: surfaceFromEnv(), log: log9 });
|
|
102396
102994
|
process.on("uncaughtException", (e) => {
|
|
102397
102995
|
try {
|
|
102398
102996
|
captureDaemonError(e, { severity: "error", context: { handler: "uncaughtException", keptAlive: true } });
|
|
@@ -103008,7 +103606,7 @@ async function runDaemon(opts = {}) {
|
|
|
103008
103606
|
let freeTicks = 0;
|
|
103009
103607
|
const lockHolder = () => {
|
|
103010
103608
|
try {
|
|
103011
|
-
return Number(
|
|
103609
|
+
return Number(readFileSync46(pidfile(), "utf-8").trim()) || 0;
|
|
103012
103610
|
} catch {
|
|
103013
103611
|
return 0;
|
|
103014
103612
|
}
|
|
@@ -103213,7 +103811,7 @@ async function runDaemon(opts = {}) {
|
|
|
103213
103811
|
if (appPid > 0 && appPid !== process.pid) {
|
|
103214
103812
|
const quitMarker = () => {
|
|
103215
103813
|
try {
|
|
103216
|
-
return Number(
|
|
103814
|
+
return Number(readFileSync46(join70(daemonDir2(), "app-quit.marker"), "utf-8").trim()) || 0;
|
|
103217
103815
|
} catch {
|
|
103218
103816
|
return 0;
|
|
103219
103817
|
}
|
|
@@ -103238,7 +103836,7 @@ async function runDaemon(opts = {}) {
|
|
|
103238
103836
|
log9(`desktop app (pid ${appPid}) is gone with NO clean-quit marker \u2014 reporting`);
|
|
103239
103837
|
const tail3 = (name) => {
|
|
103240
103838
|
try {
|
|
103241
|
-
const buf =
|
|
103839
|
+
const buf = readFileSync46(join70(daemonDir2(), name), "utf-8");
|
|
103242
103840
|
return buf.length > 4096 ? buf.slice(-4096) : buf;
|
|
103243
103841
|
} catch {
|
|
103244
103842
|
return void 0;
|
|
@@ -103272,8 +103870,8 @@ async function runDaemon(opts = {}) {
|
|
|
103272
103870
|
const daemonLogFile = join70(daemonDir2(), "daemon.log");
|
|
103273
103871
|
const capTimer = setInterval(() => {
|
|
103274
103872
|
try {
|
|
103275
|
-
if (
|
|
103276
|
-
const buf =
|
|
103873
|
+
if (existsSync36(daemonLogFile) && statSync10(daemonLogFile).size > DAEMON_LOG_CAP) {
|
|
103874
|
+
const buf = readFileSync46(daemonLogFile, "utf-8");
|
|
103277
103875
|
const kept = `\u2026[daemon.log capped at ${(/* @__PURE__ */ new Date()).toISOString()}]\u2026
|
|
103278
103876
|
` + buf.slice(-DAEMON_LOG_CAP / 2);
|
|
103279
103877
|
writeFileSync38(daemonLogFile, kept);
|
|
@@ -103604,8 +104202,8 @@ import { platform as platform6 } from "node:os";
|
|
|
103604
104202
|
|
|
103605
104203
|
// ../../packages/host-core/dist/service/launchd.js
|
|
103606
104204
|
init_credentials();
|
|
103607
|
-
import { writeFileSync as writeFileSync39, existsSync as
|
|
103608
|
-
import { dirname as
|
|
104205
|
+
import { writeFileSync as writeFileSync39, existsSync as existsSync37, mkdirSync as mkdirSync39, unlinkSync as unlinkSync7 } from "node:fs";
|
|
104206
|
+
import { dirname as dirname29, join as join71 } from "node:path";
|
|
103609
104207
|
import { homedir as homedir12, userInfo as userInfo2 } from "node:os";
|
|
103610
104208
|
|
|
103611
104209
|
// ../../packages/host-core/dist/service/types.js
|
|
@@ -103665,9 +104263,9 @@ ${env}
|
|
|
103665
104263
|
}
|
|
103666
104264
|
return {
|
|
103667
104265
|
async install(spec) {
|
|
103668
|
-
|
|
103669
|
-
|
|
103670
|
-
|
|
104266
|
+
mkdirSync39(workDirOf(spec), { recursive: true });
|
|
104267
|
+
mkdirSync39(dirname29(plistPath()), { recursive: true });
|
|
104268
|
+
mkdirSync39(dirname29(spec.logPath), { recursive: true });
|
|
103671
104269
|
writeFileSync39(plistPath(), buildPlist(spec));
|
|
103672
104270
|
await run4("launchctl", ["bootout", serviceTarget()]).catch(() => {
|
|
103673
104271
|
});
|
|
@@ -103680,7 +104278,7 @@ ${env}
|
|
|
103680
104278
|
async uninstall() {
|
|
103681
104279
|
await run4("launchctl", ["bootout", serviceTarget()]).catch(() => {
|
|
103682
104280
|
});
|
|
103683
|
-
if (
|
|
104281
|
+
if (existsSync37(plistPath())) {
|
|
103684
104282
|
try {
|
|
103685
104283
|
unlinkSync7(plistPath());
|
|
103686
104284
|
} catch {
|
|
@@ -103691,7 +104289,7 @@ ${env}
|
|
|
103691
104289
|
await this.install(spec);
|
|
103692
104290
|
},
|
|
103693
104291
|
async isInstalled() {
|
|
103694
|
-
return
|
|
104292
|
+
return existsSync37(plistPath());
|
|
103695
104293
|
},
|
|
103696
104294
|
async start() {
|
|
103697
104295
|
await run4("launchctl", ["bootstrap", domainTarget(), plistPath()]).catch(() => {
|
|
@@ -103708,7 +104306,7 @@ ${env}
|
|
|
103708
104306
|
},
|
|
103709
104307
|
async logs(follow) {
|
|
103710
104308
|
const f = logFile();
|
|
103711
|
-
if (!
|
|
104309
|
+
if (!existsSync37(f)) {
|
|
103712
104310
|
console.log(`No log yet at ${f} \u2014 has the service started?`);
|
|
103713
104311
|
return;
|
|
103714
104312
|
}
|
|
@@ -103719,8 +104317,8 @@ ${env}
|
|
|
103719
104317
|
|
|
103720
104318
|
// ../../packages/host-core/dist/service/systemd.js
|
|
103721
104319
|
init_credentials();
|
|
103722
|
-
import { writeFileSync as writeFileSync40, existsSync as
|
|
103723
|
-
import { dirname as
|
|
104320
|
+
import { writeFileSync as writeFileSync40, existsSync as existsSync38, mkdirSync as mkdirSync40, unlinkSync as unlinkSync8 } from "node:fs";
|
|
104321
|
+
import { dirname as dirname30, join as join72 } from "node:path";
|
|
103724
104322
|
import { homedir as homedir13, userInfo as userInfo3 } from "node:os";
|
|
103725
104323
|
function unitVal(v) {
|
|
103726
104324
|
return v.replace(/%/g, "%%");
|
|
@@ -103759,9 +104357,9 @@ WantedBy=default.target
|
|
|
103759
104357
|
}
|
|
103760
104358
|
return {
|
|
103761
104359
|
async install(spec) {
|
|
103762
|
-
|
|
103763
|
-
|
|
103764
|
-
|
|
104360
|
+
mkdirSync40(workDirOf(spec), { recursive: true });
|
|
104361
|
+
mkdirSync40(dirname30(unitPath()), { recursive: true });
|
|
104362
|
+
mkdirSync40(dirname30(spec.logPath), { recursive: true });
|
|
103765
104363
|
writeFileSync40(unitPath(), buildUnit2(spec));
|
|
103766
104364
|
await run4("loginctl", ["enable-linger", userInfo3().username]).catch(() => {
|
|
103767
104365
|
});
|
|
@@ -103774,7 +104372,7 @@ WantedBy=default.target
|
|
|
103774
104372
|
async uninstall() {
|
|
103775
104373
|
await run4("systemctl", ["--user", "disable", "--now", unit]).catch(() => {
|
|
103776
104374
|
});
|
|
103777
|
-
if (
|
|
104375
|
+
if (existsSync38(unitPath())) {
|
|
103778
104376
|
try {
|
|
103779
104377
|
unlinkSync8(unitPath());
|
|
103780
104378
|
} catch {
|
|
@@ -103787,7 +104385,7 @@ WantedBy=default.target
|
|
|
103787
104385
|
await this.install(spec);
|
|
103788
104386
|
},
|
|
103789
104387
|
async isInstalled() {
|
|
103790
|
-
return
|
|
104388
|
+
return existsSync38(unitPath());
|
|
103791
104389
|
},
|
|
103792
104390
|
async start() {
|
|
103793
104391
|
await run4("systemctl", ["--user", "start", unit]);
|
|
@@ -103806,8 +104404,8 @@ WantedBy=default.target
|
|
|
103806
104404
|
|
|
103807
104405
|
// ../../packages/host-core/dist/service/windows.js
|
|
103808
104406
|
init_credentials();
|
|
103809
|
-
import { writeFileSync as writeFileSync41, existsSync as
|
|
103810
|
-
import { dirname as
|
|
104407
|
+
import { writeFileSync as writeFileSync41, existsSync as existsSync39, mkdirSync as mkdirSync41, unlinkSync as unlinkSync9 } from "node:fs";
|
|
104408
|
+
import { dirname as dirname31, join as join73 } from "node:path";
|
|
103811
104409
|
function makeWindowsTask(instanceId) {
|
|
103812
104410
|
const task = `Fineguide\\TesseractHost${instanceId ? `-${instanceId}` : ""}`;
|
|
103813
104411
|
const wrapperPath = () => join73(daemonDir2(), `run-host${instanceId ? `-${instanceId}` : ""}.cmd`);
|
|
@@ -103827,9 +104425,9 @@ start "" /b ${cmd} >> "${oneLine2(spec.logPath).replace(/"/g, "")}" 2>&1\r
|
|
|
103827
104425
|
}
|
|
103828
104426
|
return {
|
|
103829
104427
|
async install(spec) {
|
|
103830
|
-
|
|
103831
|
-
|
|
103832
|
-
|
|
104428
|
+
mkdirSync41(spec.workingDirectory ?? daemonDir2(), { recursive: true });
|
|
104429
|
+
mkdirSync41(dirname31(spec.logPath), { recursive: true });
|
|
104430
|
+
mkdirSync41(dirname31(wrapperPath()), { recursive: true });
|
|
103833
104431
|
writeFileSync41(wrapperPath(), buildWrapper(spec));
|
|
103834
104432
|
await run4("schtasks", ["/Create", "/TN", task, "/SC", "ONLOGON", "/RL", "LIMITED", "/F", "/TR", `"${wrapperPath()}"`]);
|
|
103835
104433
|
await run4("schtasks", ["/Run", "/TN", task]).catch(() => {
|
|
@@ -103838,7 +104436,7 @@ start "" /b ${cmd} >> "${oneLine2(spec.logPath).replace(/"/g, "")}" 2>&1\r
|
|
|
103838
104436
|
async uninstall() {
|
|
103839
104437
|
await run4("schtasks", ["/Delete", "/TN", task, "/F"]).catch(() => {
|
|
103840
104438
|
});
|
|
103841
|
-
if (
|
|
104439
|
+
if (existsSync39(wrapperPath())) {
|
|
103842
104440
|
try {
|
|
103843
104441
|
unlinkSync9(wrapperPath());
|
|
103844
104442
|
} catch {
|
|
@@ -103868,7 +104466,7 @@ start "" /b ${cmd} >> "${oneLine2(spec.logPath).replace(/"/g, "")}" 2>&1\r
|
|
|
103868
104466
|
},
|
|
103869
104467
|
async logs(follow) {
|
|
103870
104468
|
const f = logFile();
|
|
103871
|
-
if (!
|
|
104469
|
+
if (!existsSync39(f)) {
|
|
103872
104470
|
console.log(`No log yet at ${f} \u2014 has the task run?`);
|
|
103873
104471
|
return;
|
|
103874
104472
|
}
|
|
@@ -103899,7 +104497,7 @@ init_serpapi_runner();
|
|
|
103899
104497
|
// src/auth.ts
|
|
103900
104498
|
var import_qrcode_terminal = __toESM(require_main(), 1);
|
|
103901
104499
|
import { randomUUID as randomUUID27 } from "node:crypto";
|
|
103902
|
-
import { existsSync as
|
|
104500
|
+
import { existsSync as existsSync40, rmSync as rmSync10 } from "node:fs";
|
|
103903
104501
|
import { join as join74 } from "node:path";
|
|
103904
104502
|
|
|
103905
104503
|
// src/config.ts
|
|
@@ -104102,7 +104700,7 @@ async function logout() {
|
|
|
104102
104700
|
for (const f of ["credentials.json", "status.json", "daemon.lock"]) {
|
|
104103
104701
|
try {
|
|
104104
104702
|
const p = join74(daemonDir2(), f);
|
|
104105
|
-
if (
|
|
104703
|
+
if (existsSync40(p)) rmSync10(p);
|
|
104106
104704
|
} catch {
|
|
104107
104705
|
}
|
|
104108
104706
|
}
|
|
@@ -104262,7 +104860,7 @@ function startSelfUpdater(current) {
|
|
|
104262
104860
|
// src/service.ts
|
|
104263
104861
|
import { join as join75 } from "node:path";
|
|
104264
104862
|
import { platform as platform7 } from "node:os";
|
|
104265
|
-
import { existsSync as
|
|
104863
|
+
import { existsSync as existsSync41, readFileSync as readFileSync47 } from "node:fs";
|
|
104266
104864
|
function controller(instanceId) {
|
|
104267
104865
|
const c = getServiceController(instanceId);
|
|
104268
104866
|
if (!c) {
|
|
@@ -104289,8 +104887,8 @@ var isAlive = (pid) => {
|
|
|
104289
104887
|
function runningDaemonInfo() {
|
|
104290
104888
|
const lock = join75(daemonDir2(), "daemon.lock");
|
|
104291
104889
|
try {
|
|
104292
|
-
if (!
|
|
104293
|
-
const pid = Number(
|
|
104890
|
+
if (!existsSync41(lock)) return null;
|
|
104891
|
+
const pid = Number(readFileSync47(lock, "utf-8").trim());
|
|
104294
104892
|
if (!pid || !isAlive(pid)) return null;
|
|
104295
104893
|
return { pid, device: readCredentials()?.deviceId };
|
|
104296
104894
|
} catch {
|
|
@@ -104324,7 +104922,7 @@ async function logs(instanceId, follow) {
|
|
|
104324
104922
|
}
|
|
104325
104923
|
|
|
104326
104924
|
// src/net.ts
|
|
104327
|
-
import { readFileSync as
|
|
104925
|
+
import { readFileSync as readFileSync49 } from "node:fs";
|
|
104328
104926
|
import { randomBytes as randomBytes11 } from "node:crypto";
|
|
104329
104927
|
import { hostname as hostname7 } from "node:os";
|
|
104330
104928
|
import { resolve as resolve14 } from "node:path";
|
|
@@ -104379,7 +104977,7 @@ function readOrDie(label, p) {
|
|
|
104379
104977
|
process.exit(1);
|
|
104380
104978
|
}
|
|
104381
104979
|
try {
|
|
104382
|
-
return new Uint8Array(
|
|
104980
|
+
return new Uint8Array(readFileSync49(resolve14(p)));
|
|
104383
104981
|
} catch (e) {
|
|
104384
104982
|
console.error(`net enroll: could not read --${label} ${p}: ${e instanceof Error ? e.message : e}`);
|
|
104385
104983
|
process.exit(1);
|
|
@@ -104845,8 +105443,8 @@ async function netCommand(rest, flags) {
|
|
|
104845
105443
|
// src/cli.ts
|
|
104846
105444
|
function pkgVersion() {
|
|
104847
105445
|
try {
|
|
104848
|
-
const p = join77(
|
|
104849
|
-
return JSON.parse(
|
|
105446
|
+
const p = join77(dirname32(fileURLToPath6(import.meta.url)), "..", "package.json");
|
|
105447
|
+
return JSON.parse(readFileSync50(p, "utf8")).version ?? "0.0.0";
|
|
104850
105448
|
} catch {
|
|
104851
105449
|
return "0.0.0";
|
|
104852
105450
|
}
|
|
@@ -104949,6 +105547,8 @@ Usage:
|
|
|
104949
105547
|
tesseract-agent start | stop | restart Control the service
|
|
104950
105548
|
tesseract-agent status Show the service status
|
|
104951
105549
|
tesseract-agent logs [--no-follow] Tail the service logs
|
|
105550
|
+
tesseract-agent decisions [--session ID] [--source prompt|verification|recovery] [-n N] [--json]
|
|
105551
|
+
What unattended mode decided while nobody was watching
|
|
104952
105552
|
tesseract-agent run [--engine ID] [--engine-path BIN] [--engine-env K=V ...] [--no-active-link]
|
|
104953
105553
|
Run the daemon in the foreground (Docker/manual)
|
|
104954
105554
|
tesseract-agent link add <folder> --peer <hostId> (--name <shared> | --id <id>)
|
|
@@ -105000,6 +105600,36 @@ async function confirm(question) {
|
|
|
105000
105600
|
rl.close();
|
|
105001
105601
|
}
|
|
105002
105602
|
}
|
|
105603
|
+
async function decisionsCommand(flags) {
|
|
105604
|
+
const { readUnattendedDecisions: readUnattendedDecisions2, unattendedLogPath: unattendedLogPath2 } = await Promise.resolve().then(() => (init_unattended_log(), unattended_log_exports));
|
|
105605
|
+
const limit = typeof flags.n === "string" ? Math.max(1, Number.parseInt(flags.n, 10) || 200) : 200;
|
|
105606
|
+
const source = flags.source === "prompt" || flags.source === "verification" || flags.source === "recovery" ? flags.source : void 0;
|
|
105607
|
+
const sessionId = typeof flags.session === "string" ? flags.session : void 0;
|
|
105608
|
+
const rows = readUnattendedDecisions2(limit, { ...sessionId ? { sessionId } : {}, ...source ? { source } : {} });
|
|
105609
|
+
if (flags.json === true) {
|
|
105610
|
+
for (const r of rows) console.log(JSON.stringify(r));
|
|
105611
|
+
return;
|
|
105612
|
+
}
|
|
105613
|
+
if (!rows.length) {
|
|
105614
|
+
console.log(`No unattended decisions recorded yet (${unattendedLogPath2()}).`);
|
|
105615
|
+
return;
|
|
105616
|
+
}
|
|
105617
|
+
for (const r of rows) {
|
|
105618
|
+
const when = r.ts.replace("T", " ").replace(/\.\d+Z$/, "");
|
|
105619
|
+
const who = r.engine ? ` ${r.engine}` : "";
|
|
105620
|
+
if (r.source === "verification") {
|
|
105621
|
+
const flag = r.exercised === false ? " NOT-RUN" : "";
|
|
105622
|
+
console.log(`${when}${who} verify ${r.gate} \u2192 ${r.action} (cycle ${r.cycle}${r.phaseName ? `, ${r.phaseName}` : ""}${r.blocking ? `, ${r.blocking} blocking` : ""})${flag}`);
|
|
105623
|
+
} else if (r.source === "recovery") {
|
|
105624
|
+
console.log(`${when}${who} recover ${r.kind} \u2192 ${r.action} (attempt ${r.attempt})${r.reason ? ` ${r.reason}` : ""}`);
|
|
105625
|
+
} else {
|
|
105626
|
+
const why = r.outcome === "answered" ? r.decision ?? "" : `${r.outcome}: ${r.reason ?? ""}`;
|
|
105627
|
+
console.log(`${when}${who} ${r.mode} ${r.kind}${r.subject ? `(${r.subject})` : ""} \u2192 ${r.behavior ?? "\u2014"}${r.cappedOut ? " [budget spent]" : ""} ${why}`);
|
|
105628
|
+
}
|
|
105629
|
+
}
|
|
105630
|
+
console.log(`
|
|
105631
|
+
${rows.length} decision(s) \u2014 ${unattendedLogPath2()}`);
|
|
105632
|
+
}
|
|
105003
105633
|
async function linkCommand(rest, flags) {
|
|
105004
105634
|
const sub = rest[0];
|
|
105005
105635
|
if (sub === "list") {
|
|
@@ -105060,7 +105690,7 @@ async function captureClaudeSubscription(flags) {
|
|
|
105060
105690
|
});
|
|
105061
105691
|
if (code !== 0) throw new Error(`Claude sign-in did not complete (exit ${code}).`);
|
|
105062
105692
|
const file2 = join77(home, ".credentials.json");
|
|
105063
|
-
if (
|
|
105693
|
+
if (existsSync43(file2)) return readFileSync50(file2, "utf8");
|
|
105064
105694
|
if (process.platform === "darwin") {
|
|
105065
105695
|
const value = execFileSync6("security", [
|
|
105066
105696
|
"find-generic-password",
|
|
@@ -105142,7 +105772,7 @@ async function runnerCommand(rest, flags) {
|
|
|
105142
105772
|
process.exit(1);
|
|
105143
105773
|
}
|
|
105144
105774
|
const oauthFilePath = typeof flags["oauth-file"] === "string" ? resolve15(flags["oauth-file"]) : void 0;
|
|
105145
|
-
const oauthAuthFile = oauthFilePath ?
|
|
105775
|
+
const oauthAuthFile = oauthFilePath ? readFileSync50(oauthFilePath, "utf8") : void 0;
|
|
105146
105776
|
if (oauthAuthFile) {
|
|
105147
105777
|
try {
|
|
105148
105778
|
JSON.parse(oauthAuthFile);
|
|
@@ -105251,6 +105881,9 @@ Re-run with --yes to replace it, or --instance <id> to install a SEPARATE agent.
|
|
|
105251
105881
|
case "logs":
|
|
105252
105882
|
await logs(instance, flags["no-follow"] !== true);
|
|
105253
105883
|
break;
|
|
105884
|
+
case "decisions":
|
|
105885
|
+
await decisionsCommand(flags);
|
|
105886
|
+
break;
|
|
105254
105887
|
case "link":
|
|
105255
105888
|
await linkCommand(rest, flags);
|
|
105256
105889
|
break;
|