tesseract-agent 0.4.3 → 0.4.5
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 +812 -432
- package/package.json +1 -1
package/dist-bundle/cli.js
CHANGED
|
@@ -11517,8 +11517,8 @@ var capitalizeFirstCharacter, error28;
|
|
|
11517
11517
|
var init_lt = __esm({
|
|
11518
11518
|
"../../node_modules/zod/v4/locales/lt.js"() {
|
|
11519
11519
|
init_util();
|
|
11520
|
-
capitalizeFirstCharacter = (
|
|
11521
|
-
return
|
|
11520
|
+
capitalizeFirstCharacter = (text2) => {
|
|
11521
|
+
return text2.charAt(0).toUpperCase() + text2.slice(1);
|
|
11522
11522
|
};
|
|
11523
11523
|
error28 = () => {
|
|
11524
11524
|
const Sizable = {
|
|
@@ -19350,6 +19350,213 @@ var init_cron_tools = __esm({
|
|
|
19350
19350
|
}
|
|
19351
19351
|
});
|
|
19352
19352
|
|
|
19353
|
+
// ../../packages/agent-core/dist/design-tokens.js
|
|
19354
|
+
function colorVar(name, c) {
|
|
19355
|
+
return c.cssVar ?? `--color-${name}`;
|
|
19356
|
+
}
|
|
19357
|
+
function tokensToCss(tokens) {
|
|
19358
|
+
const lines = [
|
|
19359
|
+
"/* GENERATED from design-system/tokens.json \u2014 do not edit by hand. */",
|
|
19360
|
+
":root {"
|
|
19361
|
+
];
|
|
19362
|
+
const push = (k, v) => lines.push(` ${k}: ${v};`);
|
|
19363
|
+
for (const [name, c] of Object.entries(tokens.colors ?? {}))
|
|
19364
|
+
push(colorVar(name, c), c.value);
|
|
19365
|
+
for (const [role, fam] of Object.entries(tokens.typography?.fontFamilies ?? {}))
|
|
19366
|
+
push(`--font-${role}`, fam);
|
|
19367
|
+
for (const [step, s] of Object.entries(tokens.typography?.scale ?? {}))
|
|
19368
|
+
push(`--text-${step}`, s.size);
|
|
19369
|
+
for (const [name, w] of Object.entries(tokens.typography?.weights ?? {}))
|
|
19370
|
+
push(`--weight-${name}`, String(w));
|
|
19371
|
+
for (const [step, v] of Object.entries(tokens.spacing ?? {}))
|
|
19372
|
+
push(`--space-${step}`, v);
|
|
19373
|
+
for (const [name, v] of Object.entries(tokens.radius ?? {}))
|
|
19374
|
+
push(`--radius-${name}`, v);
|
|
19375
|
+
for (const [name, v] of Object.entries(tokens.shadow ?? {}))
|
|
19376
|
+
push(`--shadow-${name}`, v);
|
|
19377
|
+
lines.push("}", "");
|
|
19378
|
+
return lines.join("\n");
|
|
19379
|
+
}
|
|
19380
|
+
function getTokenPath(tokens, dotPath) {
|
|
19381
|
+
let cur = tokens;
|
|
19382
|
+
for (const key2 of dotPath.split(".")) {
|
|
19383
|
+
if (cur == null || typeof cur !== "object")
|
|
19384
|
+
return void 0;
|
|
19385
|
+
cur = cur[key2];
|
|
19386
|
+
}
|
|
19387
|
+
return cur;
|
|
19388
|
+
}
|
|
19389
|
+
function setTokenPath(tokens, dotPath, value) {
|
|
19390
|
+
const keys = dotPath.split(".").filter(Boolean);
|
|
19391
|
+
if (keys.length === 0)
|
|
19392
|
+
throw new Error("empty token path");
|
|
19393
|
+
const root = { ...tokens };
|
|
19394
|
+
let cur = root;
|
|
19395
|
+
for (let i = 0; i < keys.length - 1; i++) {
|
|
19396
|
+
const k = keys[i];
|
|
19397
|
+
const next = cur[k];
|
|
19398
|
+
cur[k] = next && typeof next === "object" ? { ...next } : {};
|
|
19399
|
+
cur = cur[k];
|
|
19400
|
+
}
|
|
19401
|
+
cur[keys[keys.length - 1]] = value;
|
|
19402
|
+
return root;
|
|
19403
|
+
}
|
|
19404
|
+
var DESIGN_DIR, TOKENS_FILE, TOKENS_CSS_FILE, DESIGN_CLAUDE_MD, ColorToken, TypeStep, Component, DesignTokensSchema;
|
|
19405
|
+
var init_design_tokens = __esm({
|
|
19406
|
+
"../../packages/agent-core/dist/design-tokens.js"() {
|
|
19407
|
+
"use strict";
|
|
19408
|
+
init_zod();
|
|
19409
|
+
DESIGN_DIR = "design-system";
|
|
19410
|
+
TOKENS_FILE = "design-system/tokens.json";
|
|
19411
|
+
TOKENS_CSS_FILE = "design-system/tokens.css";
|
|
19412
|
+
DESIGN_CLAUDE_MD = "design-system/CLAUDE.md";
|
|
19413
|
+
ColorToken = external_exports.object({ value: external_exports.string(), cssVar: external_exports.string().optional(), role: external_exports.string().optional() });
|
|
19414
|
+
TypeStep = external_exports.object({ size: external_exports.string(), lineHeight: external_exports.string().optional(), weight: external_exports.number().optional() });
|
|
19415
|
+
Component = external_exports.object({
|
|
19416
|
+
selectorHint: external_exports.string().optional(),
|
|
19417
|
+
sourceFiles: external_exports.array(external_exports.string()).optional(),
|
|
19418
|
+
tokensUsed: external_exports.array(external_exports.string()).optional()
|
|
19419
|
+
});
|
|
19420
|
+
DesignTokensSchema = external_exports.object({
|
|
19421
|
+
$schema: external_exports.string().optional(),
|
|
19422
|
+
meta: external_exports.object({
|
|
19423
|
+
name: external_exports.string().optional(),
|
|
19424
|
+
framework: external_exports.enum(["tailwind", "css", "css-modules", "unknown"]).optional(),
|
|
19425
|
+
generatedAt: external_exports.string().optional()
|
|
19426
|
+
}).optional(),
|
|
19427
|
+
colors: external_exports.record(external_exports.string(), ColorToken).optional(),
|
|
19428
|
+
typography: external_exports.object({
|
|
19429
|
+
fontFamilies: external_exports.record(external_exports.string(), external_exports.string()).optional(),
|
|
19430
|
+
scale: external_exports.record(external_exports.string(), TypeStep).optional(),
|
|
19431
|
+
weights: external_exports.record(external_exports.string(), external_exports.number()).optional()
|
|
19432
|
+
}).optional(),
|
|
19433
|
+
spacing: external_exports.record(external_exports.string(), external_exports.string()).optional(),
|
|
19434
|
+
radius: external_exports.record(external_exports.string(), external_exports.string()).optional(),
|
|
19435
|
+
shadow: external_exports.record(external_exports.string(), external_exports.string()).optional(),
|
|
19436
|
+
components: external_exports.record(external_exports.string(), Component).optional()
|
|
19437
|
+
});
|
|
19438
|
+
}
|
|
19439
|
+
});
|
|
19440
|
+
|
|
19441
|
+
// ../../packages/agent-core/dist/design-tools.js
|
|
19442
|
+
import { tool as tool2 } from "@anthropic-ai/claude-agent-sdk";
|
|
19443
|
+
import { readFile, writeFile, mkdir } from "node:fs/promises";
|
|
19444
|
+
import { join as join4, resolve as resolve2, relative as relative2, isAbsolute as isAbsolute2 } from "node:path";
|
|
19445
|
+
function within(root, p) {
|
|
19446
|
+
const rel = relative2(resolve2(root), resolve2(p));
|
|
19447
|
+
return rel !== "" && !rel.startsWith("..") && !isAbsolute2(rel);
|
|
19448
|
+
}
|
|
19449
|
+
async function loadTokens(root) {
|
|
19450
|
+
try {
|
|
19451
|
+
const parsed = DesignTokensSchema.safeParse(JSON.parse(await readFile(join4(root, TOKENS_FILE), "utf8")));
|
|
19452
|
+
return parsed.success ? parsed.data : {};
|
|
19453
|
+
} catch {
|
|
19454
|
+
return {};
|
|
19455
|
+
}
|
|
19456
|
+
}
|
|
19457
|
+
async function saveTokens(root, tokens, regenerateCss) {
|
|
19458
|
+
const tokensAbs = join4(root, TOKENS_FILE);
|
|
19459
|
+
const cssAbs = join4(root, TOKENS_CSS_FILE);
|
|
19460
|
+
if (!within(root, tokensAbs) || !within(root, cssAbs))
|
|
19461
|
+
throw new Error("refusing to write outside the project root");
|
|
19462
|
+
await mkdir(join4(root, DESIGN_DIR), { recursive: true });
|
|
19463
|
+
await writeFile(tokensAbs, JSON.stringify(tokens, null, 2) + "\n", "utf8");
|
|
19464
|
+
if (regenerateCss)
|
|
19465
|
+
await writeFile(cssAbs, tokensToCss(tokens), "utf8");
|
|
19466
|
+
}
|
|
19467
|
+
function buildDesignTools(deps) {
|
|
19468
|
+
const needRoot = () => {
|
|
19469
|
+
const root = deps.getProjectDir();
|
|
19470
|
+
if (!root)
|
|
19471
|
+
throw new Error("No project directory is open.");
|
|
19472
|
+
return root;
|
|
19473
|
+
};
|
|
19474
|
+
return [
|
|
19475
|
+
tool2("read_design_tokens", "Read the project design system from design-system/tokens.json (colors, typography, spacing, radius, shadow, components). Call this ONCE when you need token values \u2014 do not guess hardcoded hex/sizes.", { section: external_exports.enum(["all", "colors", "typography", "spacing", "radius", "shadow", "components"]).optional().describe("Limit to one section (default: all)") }, async (args) => {
|
|
19476
|
+
const tokens = await loadTokens(needRoot());
|
|
19477
|
+
const out = !args.section || args.section === "all" ? tokens : { [args.section]: tokens[args.section] ?? {} };
|
|
19478
|
+
return text(JSON.stringify(out, null, 2));
|
|
19479
|
+
}),
|
|
19480
|
+
tool2("write_design_token", 'Set one or more design tokens by dot-path (e.g. "colors.primary.value" = "#d97757", "spacing.2" = "0.5rem") and regenerate design-system/tokens.css. Batch related edits in one call. Path-guarded to the project root.', {
|
|
19481
|
+
edits: external_exports.array(external_exports.object({
|
|
19482
|
+
path: external_exports.string().describe("Dot-path into tokens.json, e.g. colors.primary.value"),
|
|
19483
|
+
value: external_exports.union([external_exports.string(), external_exports.number()]).describe("The new value")
|
|
19484
|
+
})).describe("Edits to apply"),
|
|
19485
|
+
regenerateCss: external_exports.boolean().optional().describe("Regenerate tokens.css from the result (default: true)")
|
|
19486
|
+
}, async (args) => {
|
|
19487
|
+
const root = needRoot();
|
|
19488
|
+
let tokens = await loadTokens(root);
|
|
19489
|
+
for (const e of args.edits)
|
|
19490
|
+
tokens = setTokenPath(tokens, e.path, e.value);
|
|
19491
|
+
const validated = DesignTokensSchema.safeParse(tokens);
|
|
19492
|
+
if (!validated.success)
|
|
19493
|
+
return text(`Edit produced an invalid tokens document: ${validated.error.message}`, true);
|
|
19494
|
+
const regen = args.regenerateCss !== false;
|
|
19495
|
+
await saveTokens(root, validated.data, regen);
|
|
19496
|
+
return text(`Updated ${args.edits.length} token(s): ${args.edits.map((e) => e.path).join(", ")}${regen ? " and regenerated tokens.css" : ""}.`);
|
|
19497
|
+
}),
|
|
19498
|
+
tool2("capture_element_styles", "Read the computed CSS of an element on the live preview by CSS selector (cheap \u2014 returns text, not a screenshot). Use to learn what styles/tokens an element currently uses before editing.", {
|
|
19499
|
+
selector: external_exports.string().describe("CSS selector of the element to inspect"),
|
|
19500
|
+
properties: external_exports.array(external_exports.string()).optional().describe("CSS properties to read (default: a common set)")
|
|
19501
|
+
}, async (args) => {
|
|
19502
|
+
const props = args.properties?.length ? args.properties : STYLE_PROPS;
|
|
19503
|
+
const expr = `(() => { const el = document.querySelector(${JSON.stringify(args.selector)}); if (!el) return { error: 'no element matches ${JSON.stringify(args.selector)}' }; const cs = getComputedStyle(el); const out = {}; for (const p of ${JSON.stringify(props)}) out[p] = cs.getPropertyValue(p).trim(); return { tag: el.tagName.toLowerCase(), styles: out }; })()`;
|
|
19504
|
+
try {
|
|
19505
|
+
const result = await deps.driveBrowser("evaluate", { expression: expr });
|
|
19506
|
+
return text(typeof result === "string" ? result : JSON.stringify(result, null, 2));
|
|
19507
|
+
} catch (err) {
|
|
19508
|
+
return text(`Could not read styles (is a preview open?): ${err instanceof Error ? err.message : String(err)}`, true);
|
|
19509
|
+
}
|
|
19510
|
+
}),
|
|
19511
|
+
tool2("notify_preview_ready", "Announce that a live preview / dev server / build is now running and reachable at a URL. Call this once the app is up (e.g. after starting a web build) \u2014 the desktop opens it in the device canvas, the mobile client shows it in-chat, and a build-ready push is sent.", {
|
|
19512
|
+
url: external_exports.string().describe("The reachable preview URL, e.g. http://localhost:3000"),
|
|
19513
|
+
kind: external_exports.enum(["web", "mobile"]).optional().describe("Framing hint (default: web)")
|
|
19514
|
+
}, async (args) => {
|
|
19515
|
+
deps.notifyPreviewReady?.(args.url, args.kind);
|
|
19516
|
+
return text(`Preview announced: ${args.url}`);
|
|
19517
|
+
}),
|
|
19518
|
+
tool2("list_components", "List the design-system components recorded in tokens.json (name, source files, tokens used).", {}, async () => {
|
|
19519
|
+
const comps = (await loadTokens(needRoot())).components ?? {};
|
|
19520
|
+
const names = Object.keys(comps);
|
|
19521
|
+
if (!names.length)
|
|
19522
|
+
return text('No components recorded yet. Run the "Import Design System" skill to populate them.');
|
|
19523
|
+
return text(names.map((n) => {
|
|
19524
|
+
const c = comps[n];
|
|
19525
|
+
const src = c.sourceFiles?.length ? ` (${c.sourceFiles.join(", ")})` : "";
|
|
19526
|
+
const used = c.tokensUsed?.length ? ` \u2014 uses ${c.tokensUsed.join(", ")}` : "";
|
|
19527
|
+
return `- ${n}${src}${used}`;
|
|
19528
|
+
}).join("\n"));
|
|
19529
|
+
})
|
|
19530
|
+
];
|
|
19531
|
+
}
|
|
19532
|
+
var STYLE_PROPS, text;
|
|
19533
|
+
var init_design_tools = __esm({
|
|
19534
|
+
"../../packages/agent-core/dist/design-tools.js"() {
|
|
19535
|
+
"use strict";
|
|
19536
|
+
init_zod();
|
|
19537
|
+
init_design_tokens();
|
|
19538
|
+
STYLE_PROPS = [
|
|
19539
|
+
"color",
|
|
19540
|
+
"background-color",
|
|
19541
|
+
"font-family",
|
|
19542
|
+
"font-size",
|
|
19543
|
+
"font-weight",
|
|
19544
|
+
"line-height",
|
|
19545
|
+
"letter-spacing",
|
|
19546
|
+
"padding",
|
|
19547
|
+
"margin",
|
|
19548
|
+
"border",
|
|
19549
|
+
"border-radius",
|
|
19550
|
+
"box-shadow",
|
|
19551
|
+
"width",
|
|
19552
|
+
"height",
|
|
19553
|
+
"display",
|
|
19554
|
+
"gap"
|
|
19555
|
+
];
|
|
19556
|
+
text = (t, isError = false) => ({ content: [{ type: "text", text: t }], ...isError ? { isError: true } : {} });
|
|
19557
|
+
}
|
|
19558
|
+
});
|
|
19559
|
+
|
|
19353
19560
|
// ../../packages/agent-core/dist/narrator.js
|
|
19354
19561
|
var COALESCE_MS, LOG_CAP, ACT_CAP, NARRATE_CAP, Narrator;
|
|
19355
19562
|
var init_narrator = __esm({
|
|
@@ -19449,13 +19656,13 @@ ${s.log.map((l) => `- ${l}`).join("\n")}` : "",
|
|
|
19449
19656
|
${activity}`,
|
|
19450
19657
|
"One-line status of what it is doing now:"
|
|
19451
19658
|
].filter(Boolean).join("\n\n");
|
|
19452
|
-
const
|
|
19453
|
-
if (
|
|
19454
|
-
s.lastText =
|
|
19455
|
-
s.log.push(
|
|
19659
|
+
const text2 = (await cfg2.complete({ system, prompt, maxTokens: 40 }))?.trim().replace(/^["']|["']$/g, "");
|
|
19660
|
+
if (text2 && text2 !== s.lastText) {
|
|
19661
|
+
s.lastText = text2;
|
|
19662
|
+
s.log.push(text2);
|
|
19456
19663
|
if (s.log.length > LOG_CAP)
|
|
19457
19664
|
s.log.shift();
|
|
19458
|
-
this.emit(id,
|
|
19665
|
+
this.emit(id, text2, cfg2.engineLabel);
|
|
19459
19666
|
}
|
|
19460
19667
|
} catch {
|
|
19461
19668
|
} finally {
|
|
@@ -19562,12 +19769,12 @@ var init_trace_store = __esm({
|
|
|
19562
19769
|
|
|
19563
19770
|
// ../../packages/agent-core/dist/session-transfer.js
|
|
19564
19771
|
import { homedir } from "node:os";
|
|
19565
|
-
import { join as
|
|
19566
|
-
import { readFile, writeFile, mkdir, readdir } from "node:fs/promises";
|
|
19772
|
+
import { join as join5, dirname as dirname3, sep, resolve as resolve3 } from "node:path";
|
|
19773
|
+
import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2, readdir } from "node:fs/promises";
|
|
19567
19774
|
import { existsSync } from "node:fs";
|
|
19568
19775
|
function isInside(parent, child) {
|
|
19569
|
-
const p =
|
|
19570
|
-
const c =
|
|
19776
|
+
const p = resolve3(parent);
|
|
19777
|
+
const c = resolve3(child);
|
|
19571
19778
|
return c === p || c.startsWith(p + sep);
|
|
19572
19779
|
}
|
|
19573
19780
|
function cwdHash(cwd) {
|
|
@@ -19581,13 +19788,13 @@ function sanitizeProjectDir(cwd) {
|
|
|
19581
19788
|
return s.length <= MAX_PROJECT_DIR_LEN ? s : `${s.slice(0, MAX_PROJECT_DIR_LEN)}-${cwdHash(cwd)}`;
|
|
19582
19789
|
}
|
|
19583
19790
|
function projectsRoot() {
|
|
19584
|
-
return
|
|
19791
|
+
return join5(homedir(), ".claude", "projects");
|
|
19585
19792
|
}
|
|
19586
19793
|
function sessionDir(cwd) {
|
|
19587
|
-
return
|
|
19794
|
+
return join5(projectsRoot(), sanitizeProjectDir(cwd));
|
|
19588
19795
|
}
|
|
19589
19796
|
function sessionFile(cwd, sessionId) {
|
|
19590
|
-
return
|
|
19797
|
+
return join5(sessionDir(cwd), `${sessionId}.jsonl`);
|
|
19591
19798
|
}
|
|
19592
19799
|
async function walkFiles(root) {
|
|
19593
19800
|
const out = [];
|
|
@@ -19596,7 +19803,7 @@ async function walkFiles(root) {
|
|
|
19596
19803
|
for (const e of entries) {
|
|
19597
19804
|
const rel = prefix ? `${prefix}/${e.name}` : e.name;
|
|
19598
19805
|
if (e.isDirectory())
|
|
19599
|
-
await rec(
|
|
19806
|
+
await rec(join5(dir, e.name), rel);
|
|
19600
19807
|
else if (e.isFile())
|
|
19601
19808
|
out.push(rel);
|
|
19602
19809
|
}
|
|
@@ -19608,13 +19815,13 @@ async function exportSession(sessionId, fromCwd) {
|
|
|
19608
19815
|
const file2 = sessionFile(fromCwd, sessionId);
|
|
19609
19816
|
if (!existsSync(file2))
|
|
19610
19817
|
return null;
|
|
19611
|
-
const raw = await
|
|
19818
|
+
const raw = await readFile2(file2, "utf-8");
|
|
19612
19819
|
const lines = raw.split("\n").filter((l) => l.trim().length > 0);
|
|
19613
19820
|
const sidecar = [];
|
|
19614
|
-
const sideDir =
|
|
19821
|
+
const sideDir = join5(sessionDir(fromCwd), sessionId);
|
|
19615
19822
|
if (existsSync(sideDir)) {
|
|
19616
19823
|
for (const rel of await walkFiles(sideDir)) {
|
|
19617
|
-
sidecar.push({ rel, data: await
|
|
19824
|
+
sidecar.push({ rel, data: await readFile2(join5(sideDir, rel.split("/").join(sep))) });
|
|
19618
19825
|
}
|
|
19619
19826
|
}
|
|
19620
19827
|
return { sessionId, fromCwd, lines, sidecar };
|
|
@@ -19622,22 +19829,22 @@ async function exportSession(sessionId, fromCwd) {
|
|
|
19622
19829
|
function escapeRe(s) {
|
|
19623
19830
|
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
19624
19831
|
}
|
|
19625
|
-
function rekey(
|
|
19626
|
-
return
|
|
19832
|
+
function rekey(text2, fromCwd, toCwd) {
|
|
19833
|
+
return text2.replace(new RegExp(escapeRe(fromCwd) + '(?=["/\\\\]|$)', "g"), () => toCwd);
|
|
19627
19834
|
}
|
|
19628
19835
|
async function importSession(exp, toCwd) {
|
|
19629
19836
|
const destDir = sessionDir(toCwd);
|
|
19630
|
-
await
|
|
19631
|
-
const destFile =
|
|
19632
|
-
await
|
|
19633
|
-
const sideRoot =
|
|
19837
|
+
await mkdir2(destDir, { recursive: true });
|
|
19838
|
+
const destFile = join5(destDir, `${exp.sessionId}.jsonl`);
|
|
19839
|
+
await writeFile2(destFile, exp.lines.map((l) => rekey(l, exp.fromCwd, toCwd)).join("\n") + "\n");
|
|
19840
|
+
const sideRoot = join5(destDir, exp.sessionId);
|
|
19634
19841
|
for (const s of exp.sidecar) {
|
|
19635
|
-
const dest =
|
|
19842
|
+
const dest = join5(sideRoot, s.rel.split("/").join(sep));
|
|
19636
19843
|
if (!isInside(sideRoot, dest))
|
|
19637
19844
|
continue;
|
|
19638
|
-
await
|
|
19845
|
+
await mkdir2(dirname3(dest), { recursive: true });
|
|
19639
19846
|
const data = s.rel.endsWith(".jsonl") || s.rel.endsWith(".json") ? Buffer.from(rekey(s.data.toString("utf-8"), exp.fromCwd, toCwd), "utf-8") : s.data;
|
|
19640
|
-
await
|
|
19847
|
+
await writeFile2(dest, data);
|
|
19641
19848
|
}
|
|
19642
19849
|
return destFile;
|
|
19643
19850
|
}
|
|
@@ -19656,7 +19863,7 @@ var init_session_transfer = __esm({
|
|
|
19656
19863
|
});
|
|
19657
19864
|
|
|
19658
19865
|
// ../../packages/agent-core/dist/session-store.js
|
|
19659
|
-
import { readFile as
|
|
19866
|
+
import { readFile as readFile3, stat } from "node:fs/promises";
|
|
19660
19867
|
import { listSessions, getSessionMessages, forkSession } from "@anthropic-ai/claude-agent-sdk";
|
|
19661
19868
|
function toSessionInfo(s) {
|
|
19662
19869
|
const fromFirst = stripPromptPrefix(s.firstPrompt ?? "").slice(0, 80);
|
|
@@ -19702,9 +19909,9 @@ function transcriptMatches(raw, q) {
|
|
|
19702
19909
|
}
|
|
19703
19910
|
return false;
|
|
19704
19911
|
}
|
|
19705
|
-
function stripPromptPrefix(
|
|
19912
|
+
function stripPromptPrefix(text2) {
|
|
19706
19913
|
const isMetadata = (l) => l.startsWith("I'm working on the page:") || l.startsWith("Selected elements:") || l.startsWith("Element ") || l.startsWith(" DOM Path:") || l.startsWith(" XPath:") || l.startsWith(" CSS:") || l.startsWith(" HTML:") || l.startsWith(" Text:") || l.startsWith(" Position:") || l.startsWith("Use the xpath") || l.startsWith("[") && l.includes("image(s) attached");
|
|
19707
|
-
const userLines =
|
|
19914
|
+
const userLines = text2.split("\n").filter((l) => !isMetadata(l));
|
|
19708
19915
|
return userLines.join("\n").trim();
|
|
19709
19916
|
}
|
|
19710
19917
|
function extractBlocks(message) {
|
|
@@ -19723,13 +19930,13 @@ function extractBlocks(message) {
|
|
|
19723
19930
|
continue;
|
|
19724
19931
|
const b = block;
|
|
19725
19932
|
if (b.type === "thinking" && typeof b.thinking === "string") {
|
|
19726
|
-
const
|
|
19727
|
-
if (
|
|
19728
|
-
blocks.push({ kind: "thinking", content:
|
|
19933
|
+
const text2 = b.thinking.trim();
|
|
19934
|
+
if (text2)
|
|
19935
|
+
blocks.push({ kind: "thinking", content: text2 });
|
|
19729
19936
|
} else if (b.type === "text" && typeof b.text === "string") {
|
|
19730
|
-
const
|
|
19731
|
-
if (
|
|
19732
|
-
blocks.push({ kind: "text", content:
|
|
19937
|
+
const text2 = b.text.trim();
|
|
19938
|
+
if (text2 && !text2.startsWith("<ide_") && !text2.startsWith("<system-reminder>")) {
|
|
19939
|
+
blocks.push({ kind: "text", content: text2 });
|
|
19733
19940
|
}
|
|
19734
19941
|
} else if (b.type === "tool_use") {
|
|
19735
19942
|
const name = b.name ?? "tool";
|
|
@@ -19821,7 +20028,7 @@ var init_session_store = __esm({
|
|
|
19821
20028
|
const file2 = sessionFile(s.cwd, s.sessionId);
|
|
19822
20029
|
const st = await stat(file2);
|
|
19823
20030
|
if (st.size <= SEARCH_MAX_FILE_BYTES) {
|
|
19824
|
-
const raw = await
|
|
20031
|
+
const raw = await readFile3(file2, "utf-8");
|
|
19825
20032
|
if (transcriptMatches(raw, q))
|
|
19826
20033
|
out.push(info);
|
|
19827
20034
|
}
|
|
@@ -19891,11 +20098,11 @@ var init_log = __esm({
|
|
|
19891
20098
|
});
|
|
19892
20099
|
|
|
19893
20100
|
// ../../packages/agent-core/dist/session-usage.js
|
|
19894
|
-
import { readFile as
|
|
20101
|
+
import { readFile as readFile4 } from "node:fs/promises";
|
|
19895
20102
|
import { execFile } from "node:child_process";
|
|
19896
20103
|
import { promisify } from "node:util";
|
|
19897
20104
|
import { homedir as homedir2 } from "node:os";
|
|
19898
|
-
import { join as
|
|
20105
|
+
import { join as join6 } from "node:path";
|
|
19899
20106
|
function tokenFromCredsBlob(raw) {
|
|
19900
20107
|
try {
|
|
19901
20108
|
const j = JSON.parse(raw);
|
|
@@ -19909,7 +20116,7 @@ async function tokenFromConfigDir(dir) {
|
|
|
19909
20116
|
if (!d)
|
|
19910
20117
|
return null;
|
|
19911
20118
|
try {
|
|
19912
|
-
return tokenFromCredsBlob(await
|
|
20119
|
+
return tokenFromCredsBlob(await readFile4(join6(d, ".credentials.json"), "utf8"));
|
|
19913
20120
|
} catch {
|
|
19914
20121
|
return null;
|
|
19915
20122
|
}
|
|
@@ -19924,7 +20131,7 @@ async function resolveOauthToken(env) {
|
|
|
19924
20131
|
const ambientTok = process.env.CLAUDE_CODE_OAUTH_TOKEN?.trim();
|
|
19925
20132
|
if (ambientTok)
|
|
19926
20133
|
return ambientTok;
|
|
19927
|
-
const fromAmbientDir = await tokenFromConfigDir(process.env.CLAUDE_CONFIG_DIR ??
|
|
20134
|
+
const fromAmbientDir = await tokenFromConfigDir(process.env.CLAUDE_CONFIG_DIR ?? join6(homedir2(), ".claude"));
|
|
19928
20135
|
if (fromAmbientDir)
|
|
19929
20136
|
return fromAmbientDir;
|
|
19930
20137
|
if (process.platform === "darwin") {
|
|
@@ -20042,11 +20249,11 @@ var init_session_usage = __esm({
|
|
|
20042
20249
|
|
|
20043
20250
|
// ../../packages/agent-core/dist/agent-manager.js
|
|
20044
20251
|
import { query, createSdkMcpServer } from "@anthropic-ai/claude-agent-sdk";
|
|
20045
|
-
import { writeFile as
|
|
20252
|
+
import { writeFile as writeFile3, mkdir as mkdir3, readFile as readFile5 } from "node:fs/promises";
|
|
20046
20253
|
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
20047
20254
|
import { tmpdir } from "node:os";
|
|
20048
|
-
import { join as
|
|
20049
|
-
import { existsSync as existsSync2 } from "node:fs";
|
|
20255
|
+
import { join as join7, dirname as dirname4 } from "node:path";
|
|
20256
|
+
import { existsSync as existsSync2, readFileSync as readFileSync3 } from "node:fs";
|
|
20050
20257
|
import { fileURLToPath } from "node:url";
|
|
20051
20258
|
import { createRequire } from "node:module";
|
|
20052
20259
|
import { createServer } from "node:net";
|
|
@@ -20054,7 +20261,7 @@ import { spawn, execSync } from "node:child_process";
|
|
|
20054
20261
|
function findClaudeCliJs() {
|
|
20055
20262
|
const require2 = createRequire(import.meta.url);
|
|
20056
20263
|
const sdkMain = require2.resolve("@anthropic-ai/claude-agent-sdk");
|
|
20057
|
-
const cliJs =
|
|
20264
|
+
const cliJs = join7(dirname4(sdkMain), "cli.js");
|
|
20058
20265
|
if (!existsSync2(cliJs)) {
|
|
20059
20266
|
throw new Error(`Claude Agent SDK cli.js not found at ${cliJs}. The installed SDK version may not ship cli.js \u2014 apps/host/package.json pins @anthropic-ai/claude-agent-sdk to a version that includes it.`);
|
|
20060
20267
|
}
|
|
@@ -20158,15 +20365,15 @@ ${plan}`;
|
|
|
20158
20365
|
}
|
|
20159
20366
|
}
|
|
20160
20367
|
function flattenToolResultContent(content) {
|
|
20161
|
-
let
|
|
20368
|
+
let text2 = "";
|
|
20162
20369
|
if (typeof content === "string")
|
|
20163
|
-
|
|
20370
|
+
text2 = content;
|
|
20164
20371
|
else if (Array.isArray(content)) {
|
|
20165
|
-
|
|
20372
|
+
text2 = content.filter((b) => b && typeof b === "object" && b.type === "text").map((b) => String(b.text ?? "")).join("\n");
|
|
20166
20373
|
}
|
|
20167
|
-
if (
|
|
20168
|
-
return { text:
|
|
20169
|
-
return { text, truncated: false };
|
|
20374
|
+
if (text2.length > TOOL_RESULT_CAP)
|
|
20375
|
+
return { text: text2.slice(0, TOOL_RESULT_CAP), truncated: true };
|
|
20376
|
+
return { text: text2, truncated: false };
|
|
20170
20377
|
}
|
|
20171
20378
|
function extractImages(content) {
|
|
20172
20379
|
if (!Array.isArray(content))
|
|
@@ -20209,7 +20416,7 @@ function editedPathOf(toolInput) {
|
|
|
20209
20416
|
}
|
|
20210
20417
|
async function snapshotFile(path5) {
|
|
20211
20418
|
try {
|
|
20212
|
-
const buf = await
|
|
20419
|
+
const buf = await readFile5(path5);
|
|
20213
20420
|
if (buf.length > EDIT_PREVIEW_CAP)
|
|
20214
20421
|
return { noPreview: true };
|
|
20215
20422
|
if (buf.subarray(0, 8192).includes(0))
|
|
@@ -20229,12 +20436,42 @@ function sourcesEqual(a, b) {
|
|
|
20229
20436
|
return false;
|
|
20230
20437
|
return true;
|
|
20231
20438
|
}
|
|
20439
|
+
function buildMobileClause(dir) {
|
|
20440
|
+
try {
|
|
20441
|
+
let fw = "";
|
|
20442
|
+
let runCmd = "";
|
|
20443
|
+
if (existsSync2(join7(dir, "pubspec.yaml"))) {
|
|
20444
|
+
fw = "Flutter";
|
|
20445
|
+
runCmd = "flutter run -d chrome";
|
|
20446
|
+
} else if (existsSync2(join7(dir, "package.json"))) {
|
|
20447
|
+
const pkg = JSON.parse(readFileSync3(join7(dir, "package.json"), "utf8"));
|
|
20448
|
+
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
20449
|
+
if (deps.expo) {
|
|
20450
|
+
fw = "Expo";
|
|
20451
|
+
runCmd = "npx expo start --web";
|
|
20452
|
+
} else if (deps["react-native"]) {
|
|
20453
|
+
fw = "React Native";
|
|
20454
|
+
runCmd = "npm run web (react-native-web)";
|
|
20455
|
+
}
|
|
20456
|
+
}
|
|
20457
|
+
if (!fw)
|
|
20458
|
+
return "";
|
|
20459
|
+
return `
|
|
20460
|
+
|
|
20461
|
+
MOBILE (${fw}):
|
|
20462
|
+
- For a fast live preview, run the app AS WEB (\`${runCmd}\`) and tell the user the localhost URL \u2014 Tesseract shows it in a phone-framed canvas where elements can be picked and edited. Use a real device/simulator only when native-specific behavior matters.`;
|
|
20463
|
+
} catch {
|
|
20464
|
+
return "";
|
|
20465
|
+
}
|
|
20466
|
+
}
|
|
20232
20467
|
var cachedNodeExe, HUMAN_READABLE_FIELDS, TOOL_RESULT_CAP, MAX_RESULT_IMAGES, MAX_IMAGE_BASE64, PERMISSION_MODES, EDIT_PREVIEW_CAP, AsyncMessagePump, IDLE_REAP_MS, MODERATE_IDLE_MS, STEER_COALESCE_MS, AgentManager;
|
|
20233
20468
|
var init_agent_manager = __esm({
|
|
20234
20469
|
"../../packages/agent-core/dist/agent-manager.js"() {
|
|
20235
20470
|
"use strict";
|
|
20236
20471
|
init_dist();
|
|
20237
20472
|
init_cron_tools();
|
|
20473
|
+
init_design_tools();
|
|
20474
|
+
init_design_tokens();
|
|
20238
20475
|
init_narrator();
|
|
20239
20476
|
init_plan_splitter();
|
|
20240
20477
|
init_trace_store();
|
|
@@ -20277,7 +20514,7 @@ var init_agent_manager = __esm({
|
|
|
20277
20514
|
if (this.closed) {
|
|
20278
20515
|
return Promise.resolve({ value: void 0, done: true });
|
|
20279
20516
|
}
|
|
20280
|
-
return new Promise((
|
|
20517
|
+
return new Promise((resolve9) => this.resolvers.push(resolve9));
|
|
20281
20518
|
},
|
|
20282
20519
|
return: () => {
|
|
20283
20520
|
this.end();
|
|
@@ -20303,6 +20540,10 @@ var init_agent_manager = __esm({
|
|
|
20303
20540
|
/** requestId → the originating browser-cli socket, for unicast responses.
|
|
20304
20541
|
* browser-cli is one-shot, so the entry is deleted on the first write. */
|
|
20305
20542
|
pendingResponses = /* @__PURE__ */ new Map();
|
|
20543
|
+
/** Resolvers for HOST-originated browser requests (design tools), keyed by
|
|
20544
|
+
* requestId — disjoint from pendingResponses (browser-cli sockets). Resolved by
|
|
20545
|
+
* sendBrowserResponse when the host replies. */
|
|
20546
|
+
pendingBrowserResolvers = /* @__PURE__ */ new Map();
|
|
20306
20547
|
/** requestId → a parked canUseTool decision. The Promise resolves when the
|
|
20307
20548
|
* client replies with chat:permission (→ respondToPermission) or the turn is
|
|
20308
20549
|
* aborted (→ deny). `suggestions` is echoed back as updatedPermissions when the
|
|
@@ -20415,8 +20656,8 @@ var init_agent_manager = __esm({
|
|
|
20415
20656
|
this.send = send2;
|
|
20416
20657
|
this.onBrowserRequest = onBrowserRequest;
|
|
20417
20658
|
const __dirname = dirname4(fileURLToPath(import.meta.url));
|
|
20418
|
-
this.browserCliPath =
|
|
20419
|
-
this.narrator = new Narrator((sessionId,
|
|
20659
|
+
this.browserCliPath = join7(__dirname, "browser-cli.js");
|
|
20660
|
+
this.narrator = new Narrator((sessionId, text2, engineLabel) => this.send({ type: "agent:narration", sessionId, text: text2, ...engineLabel ? { engineLabel } : {} }, this.liveSessions.get(sessionId)?.origin));
|
|
20420
20661
|
}
|
|
20421
20662
|
/** Inject (or clear) the cheap model used for the live status narration. The
|
|
20422
20663
|
* host resolves creds and builds the completion fn (keeping secrets host-side). */
|
|
@@ -20443,7 +20684,7 @@ var init_agent_manager = __esm({
|
|
|
20443
20684
|
* (no shared-socket "which session?" race) with ZERO changes to browser-cli.
|
|
20444
20685
|
*/
|
|
20445
20686
|
startSessionListener(live) {
|
|
20446
|
-
return new Promise((
|
|
20687
|
+
return new Promise((resolve9) => {
|
|
20447
20688
|
const server = createServer((socket2) => {
|
|
20448
20689
|
live.ipcSockets.add(socket2);
|
|
20449
20690
|
let buffer = "";
|
|
@@ -20475,11 +20716,21 @@ var init_agent_manager = __esm({
|
|
|
20475
20716
|
const addr = server.address();
|
|
20476
20717
|
live.ipcPort = typeof addr === "object" && addr ? addr.port : 0;
|
|
20477
20718
|
log("Session IPC listener on port", live.ipcPort, "for", live.sessionId || live.clientRequestId || "(pending)");
|
|
20478
|
-
|
|
20719
|
+
resolve9();
|
|
20479
20720
|
});
|
|
20480
20721
|
});
|
|
20481
20722
|
}
|
|
20482
20723
|
sendBrowserResponse(requestId, result, error51) {
|
|
20724
|
+
const pending = this.pendingBrowserResolvers.get(requestId);
|
|
20725
|
+
if (pending) {
|
|
20726
|
+
this.pendingBrowserResolvers.delete(requestId);
|
|
20727
|
+
clearTimeout(pending.timer);
|
|
20728
|
+
if (error51)
|
|
20729
|
+
pending.reject(new Error(error51));
|
|
20730
|
+
else
|
|
20731
|
+
pending.resolve(result);
|
|
20732
|
+
return;
|
|
20733
|
+
}
|
|
20483
20734
|
const socket2 = this.pendingResponses.get(requestId);
|
|
20484
20735
|
if (!socket2)
|
|
20485
20736
|
return;
|
|
@@ -20489,6 +20740,28 @@ var init_agent_manager = __esm({
|
|
|
20489
20740
|
} catch {
|
|
20490
20741
|
}
|
|
20491
20742
|
}
|
|
20743
|
+
/** Drive THIS session's connected browser from host-side tool code and await the
|
|
20744
|
+
* result (mirrors the browser-cli round-trip, but in-process). Used by the design
|
|
20745
|
+
* MCP tools (capture_element_styles). Rejects after 15s if the host never replies
|
|
20746
|
+
* (e.g. no preview open). Reuses the existing onBrowserRequest/sendBrowserResponse
|
|
20747
|
+
* pair — the host neither knows nor cares the requestId originated here. */
|
|
20748
|
+
requestBrowser(live, action, params) {
|
|
20749
|
+
return new Promise((resolve9, reject) => {
|
|
20750
|
+
const requestId = `design:${randomUUID2()}`;
|
|
20751
|
+
const timer = setTimeout(() => {
|
|
20752
|
+
this.pendingBrowserResolvers.delete(requestId);
|
|
20753
|
+
reject(new Error("browser request timed out"));
|
|
20754
|
+
}, 15e3);
|
|
20755
|
+
this.pendingBrowserResolvers.set(requestId, { resolve: resolve9, reject, timer });
|
|
20756
|
+
try {
|
|
20757
|
+
this.onBrowserRequest(requestId, action, params, live.browserId, live.windowId);
|
|
20758
|
+
} catch (err) {
|
|
20759
|
+
this.pendingBrowserResolvers.delete(requestId);
|
|
20760
|
+
clearTimeout(timer);
|
|
20761
|
+
reject(err instanceof Error ? err : new Error(String(err)));
|
|
20762
|
+
}
|
|
20763
|
+
});
|
|
20764
|
+
}
|
|
20492
20765
|
/** Resolve a parked canUseTool decision (client replied with chat:permission).
|
|
20493
20766
|
* No-op if the request is unknown (already resolved / aborted). On "allow &
|
|
20494
20767
|
* don't ask again" (persist) we hand the SDK its own suggested permission
|
|
@@ -20595,9 +20868,9 @@ var init_agent_manager = __esm({
|
|
|
20595
20868
|
const transcripts = [];
|
|
20596
20869
|
for (const sid of sessionIds) {
|
|
20597
20870
|
const msgs = await this.sessionStore.getSessionMessages(sid).catch(() => []);
|
|
20598
|
-
const
|
|
20599
|
-
if (
|
|
20600
|
-
transcripts.push(
|
|
20871
|
+
const text2 = msgs.map((m) => `${m.role === "user" ? "User" : "Assistant"}: ${m.content}`).join("\n").slice(0, PER_SOURCE_CAP);
|
|
20872
|
+
if (text2.trim())
|
|
20873
|
+
transcripts.push(text2);
|
|
20601
20874
|
}
|
|
20602
20875
|
if (transcripts.length === 0)
|
|
20603
20876
|
return;
|
|
@@ -20676,6 +20949,11 @@ ${t}`)
|
|
|
20676
20949
|
const cli = `ELECTRON_RUN_AS_NODE=1 "${process.execPath}" "${this.browserCliPath}"`;
|
|
20677
20950
|
const pageInfo = url2 ? `
|
|
20678
20951
|
The user's current browser tab is: ${url2}` : "";
|
|
20952
|
+
const designClause = this.projectDir && existsSync2(join7(this.projectDir, TOKENS_FILE)) ? `
|
|
20953
|
+
|
|
20954
|
+
DESIGN SYSTEM:
|
|
20955
|
+
- 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.` : "";
|
|
20956
|
+
const mobileClause = this.projectDir ? buildMobileClause(this.projectDir) : "";
|
|
20679
20957
|
return `You are Fineguide Tesseract, an AI assistant helping developers inspect and fix web pages.
|
|
20680
20958
|
You have direct access to the browser connected to this conversation via CLI tools. Use the Bash tool to call them:${pageInfo}
|
|
20681
20959
|
|
|
@@ -20692,19 +20970,19 @@ CRITICAL RULES:
|
|
|
20692
20970
|
- Use screenshot to see the visual state.
|
|
20693
20971
|
- When element selectors are provided, use click or evaluate to interact.
|
|
20694
20972
|
- You can read and edit project source files if a project directory is configured.
|
|
20695
|
-
- Always confirm before making destructive changes to source files
|
|
20973
|
+
- Always confirm before making destructive changes to source files.${designClause}${mobileClause}`;
|
|
20696
20974
|
}
|
|
20697
20975
|
async sendMessage(params) {
|
|
20698
20976
|
if (params.images && params.images.length > 0) {
|
|
20699
|
-
const imgDir =
|
|
20700
|
-
await
|
|
20977
|
+
const imgDir = join7(tmpdir(), "ccb-images");
|
|
20978
|
+
await mkdir3(imgDir, { recursive: true });
|
|
20701
20979
|
const paths = [];
|
|
20702
20980
|
for (let i = 0; i < params.images.length; i++) {
|
|
20703
20981
|
const match = params.images[i].match(/^data:image\/(\w+);base64,(.+)$/);
|
|
20704
20982
|
if (match) {
|
|
20705
20983
|
const ext = match[1] === "jpeg" ? "jpg" : match[1];
|
|
20706
|
-
const filePath =
|
|
20707
|
-
await
|
|
20984
|
+
const filePath = join7(imgDir, `img-${process.pid}-${Date.now()}-${randomUUID2().slice(0, 8)}-${i}.${ext}`);
|
|
20985
|
+
await writeFile3(filePath, Buffer.from(match[2], "base64"));
|
|
20708
20986
|
paths.push(filePath);
|
|
20709
20987
|
}
|
|
20710
20988
|
}
|
|
@@ -20713,8 +20991,8 @@ CRITICAL RULES:
|
|
|
20713
20991
|
}
|
|
20714
20992
|
}
|
|
20715
20993
|
if (params.files && params.files.length > 0) {
|
|
20716
|
-
const fileDir =
|
|
20717
|
-
await
|
|
20994
|
+
const fileDir = join7(tmpdir(), "ccb-files");
|
|
20995
|
+
await mkdir3(fileDir, { recursive: true });
|
|
20718
20996
|
const paths = [];
|
|
20719
20997
|
for (let i = 0; i < params.files.length; i++) {
|
|
20720
20998
|
const f = params.files[i];
|
|
@@ -20722,8 +21000,8 @@ CRITICAL RULES:
|
|
|
20722
21000
|
if (!match)
|
|
20723
21001
|
continue;
|
|
20724
21002
|
const safe = (f.name || `file-${i}`).replace(/[^\w.\-]+/g, "_").slice(-100);
|
|
20725
|
-
const filePath =
|
|
20726
|
-
await
|
|
21003
|
+
const filePath = join7(fileDir, `${process.pid}-${Date.now()}-${randomUUID2().slice(0, 8)}-${i}-${safe}`);
|
|
21004
|
+
await writeFile3(filePath, Buffer.from(match[1], "base64"));
|
|
20727
21005
|
paths.push(filePath);
|
|
20728
21006
|
}
|
|
20729
21007
|
if (paths.length > 0) {
|
|
@@ -20901,6 +21179,15 @@ CRITICAL RULES:
|
|
|
20901
21179
|
const cronTools = buildCronTools({ store: this.cronStore, pushEnabled: this.cronToolsDeps.pushEnabled, dispatchPush: this.cronToolsDeps.dispatchPush, getSessionId: () => live.sessionId || void 0 });
|
|
20902
21180
|
mcp["tesseract-cron"] = createSdkMcpServer({ name: "tesseract-cron", version: "0.1.0", tools: cronTools });
|
|
20903
21181
|
}
|
|
21182
|
+
if (this.projectDir) {
|
|
21183
|
+
const designTools = buildDesignTools({
|
|
21184
|
+
getProjectDir: () => this.projectDir,
|
|
21185
|
+
driveBrowser: (action, params2) => this.requestBrowser(live, action, params2),
|
|
21186
|
+
getSessionId: () => live.sessionId || void 0,
|
|
21187
|
+
notifyPreviewReady: (url2, kind) => this.send({ type: "agent:preview_ready", sessionId: live.sessionId, previewUrl: url2, kind, ts: Date.now() }, live.origin)
|
|
21188
|
+
});
|
|
21189
|
+
mcp["tesseract-design"] = createSdkMcpServer({ name: "tesseract-design", version: "0.1.0", tools: designTools });
|
|
21190
|
+
}
|
|
20904
21191
|
return Object.keys(mcp).length > 0 ? { mcpServers: mcp } : {};
|
|
20905
21192
|
})(),
|
|
20906
21193
|
// Skills (Epic H): a local plugin bundling the enabled ClawHub skills, so the SDK
|
|
@@ -20914,20 +21201,20 @@ CRITICAL RULES:
|
|
|
20914
21201
|
// in acceptEdits, everything risky in default/auto). We park a Promise and
|
|
20915
21202
|
// resolve it when the client replies via chat:permission (respondToPermission),
|
|
20916
21203
|
// or deny on abort so an interrupted turn never leaks a pending decision.
|
|
20917
|
-
canUseTool: (toolName, input, opts) => new Promise((
|
|
21204
|
+
canUseTool: (toolName, input, opts) => new Promise((resolve9) => {
|
|
20918
21205
|
const requestId = randomUUID2();
|
|
20919
21206
|
const onAbort = () => {
|
|
20920
21207
|
if (this.pendingPermissions.delete(requestId)) {
|
|
20921
|
-
|
|
21208
|
+
resolve9({ behavior: "deny", message: "Interrupted.", interrupt: true });
|
|
20922
21209
|
}
|
|
20923
21210
|
};
|
|
20924
21211
|
const cleanup2 = () => opts.signal.removeEventListener("abort", onAbort);
|
|
20925
21212
|
if (opts.signal.aborted) {
|
|
20926
|
-
|
|
21213
|
+
resolve9({ behavior: "deny", message: "Interrupted.", interrupt: true });
|
|
20927
21214
|
return;
|
|
20928
21215
|
}
|
|
20929
21216
|
opts.signal.addEventListener("abort", onAbort, { once: true });
|
|
20930
|
-
this.pendingPermissions.set(requestId, { resolve:
|
|
21217
|
+
this.pendingPermissions.set(requestId, { resolve: resolve9, suggestions: opts.suggestions, cleanup: cleanup2, origin: live.origin });
|
|
20931
21218
|
const evt = {
|
|
20932
21219
|
type: "agent:permission_request",
|
|
20933
21220
|
sessionId: live.sessionId,
|
|
@@ -20953,19 +21240,19 @@ CRITICAL RULES:
|
|
|
20953
21240
|
// M5 H6 — an MCP server requesting user input (a form, or url-based OAuth).
|
|
20954
21241
|
// Default is auto-cancel; we park a Promise and raise an inline card, then
|
|
20955
21242
|
// resolve it from chat:elicitation (respondToElicitation). Mirrors canUseTool.
|
|
20956
|
-
onElicitation: (request, opts) => new Promise((
|
|
21243
|
+
onElicitation: (request, opts) => new Promise((resolve9) => {
|
|
20957
21244
|
const requestId = randomUUID2();
|
|
20958
21245
|
const onAbort = () => {
|
|
20959
21246
|
if (this.pendingElicitations.delete(requestId))
|
|
20960
|
-
|
|
21247
|
+
resolve9({ action: "cancel" });
|
|
20961
21248
|
};
|
|
20962
21249
|
const cleanup2 = () => opts.signal.removeEventListener("abort", onAbort);
|
|
20963
21250
|
if (opts.signal.aborted) {
|
|
20964
|
-
|
|
21251
|
+
resolve9({ action: "cancel" });
|
|
20965
21252
|
return;
|
|
20966
21253
|
}
|
|
20967
21254
|
opts.signal.addEventListener("abort", onAbort, { once: true });
|
|
20968
|
-
this.pendingElicitations.set(requestId, { resolve:
|
|
21255
|
+
this.pendingElicitations.set(requestId, { resolve: resolve9, cleanup: cleanup2, origin: live.origin });
|
|
20969
21256
|
const evt = {
|
|
20970
21257
|
type: "agent:elicitation_request",
|
|
20971
21258
|
sessionId: live.sessionId,
|
|
@@ -21185,26 +21472,26 @@ CRITICAL RULES:
|
|
|
21185
21472
|
emit({ type: "chat:stream", sessionId: sid, delta: event.delta.thinking, messageId: message.uuid, kind: "thinking", ...parentField });
|
|
21186
21473
|
}
|
|
21187
21474
|
if (event.delta?.type === "text_delta" && event.delta.text) {
|
|
21188
|
-
const
|
|
21189
|
-
if (/<(?:tool_call|tool_result|function_calls|antml:function_calls)[\s>]/i.test(
|
|
21475
|
+
const text2 = event.delta.text;
|
|
21476
|
+
if (/<(?:tool_call|tool_result|function_calls|antml:function_calls)[\s>]/i.test(text2)) {
|
|
21190
21477
|
insideXmlByKey.set(key2, true);
|
|
21191
21478
|
break;
|
|
21192
21479
|
}
|
|
21193
21480
|
if (insideXmlByKey.get(key2)) {
|
|
21194
|
-
if (/<\/(?:tool_call|tool_result|function_calls|antml:function_calls)\s*>/i.test(
|
|
21481
|
+
if (/<\/(?:tool_call|tool_result|function_calls|antml:function_calls)\s*>/i.test(text2)) {
|
|
21195
21482
|
insideXmlByKey.set(key2, false);
|
|
21196
21483
|
}
|
|
21197
21484
|
break;
|
|
21198
21485
|
}
|
|
21199
|
-
if (/<\/?(?:invoke|antml:invoke|antml:parameter)[\s>]/.test(
|
|
21486
|
+
if (/<\/?(?:invoke|antml:invoke|antml:parameter)[\s>]/.test(text2))
|
|
21200
21487
|
break;
|
|
21201
|
-
if (/<parameter\s+name=/.test(
|
|
21488
|
+
if (/<parameter\s+name=/.test(text2))
|
|
21202
21489
|
break;
|
|
21203
|
-
if (/^\s*<\/(?:parameter|invoke|function_calls)>\s*$/.test(
|
|
21490
|
+
if (/^\s*<\/(?:parameter|invoke|function_calls)>\s*$/.test(text2))
|
|
21204
21491
|
break;
|
|
21205
21492
|
if (parentToolUseId === void 0)
|
|
21206
21493
|
turnStreamed = true;
|
|
21207
|
-
emit({ type: "chat:stream", sessionId: sid, delta:
|
|
21494
|
+
emit({ type: "chat:stream", sessionId: sid, delta: text2, messageId: message.uuid, kind: "text", ...parentField });
|
|
21208
21495
|
}
|
|
21209
21496
|
if (event.delta?.type === "input_json_delta" && event.delta.partial_json) {
|
|
21210
21497
|
const acc = blockAcc.get(key2);
|
|
@@ -21447,11 +21734,11 @@ Compacted earlier context.` });
|
|
|
21447
21734
|
case "files_persisted":
|
|
21448
21735
|
break;
|
|
21449
21736
|
default: {
|
|
21450
|
-
const
|
|
21737
|
+
const text2 = extractHumanReadable(m);
|
|
21451
21738
|
const header = systemHeader("system", subtype);
|
|
21452
|
-
const body =
|
|
21739
|
+
const body = text2 ? `${header}
|
|
21453
21740
|
|
|
21454
|
-
${
|
|
21741
|
+
${text2}` : header;
|
|
21455
21742
|
emit({ type: "agent:tool_use", sessionId: sid, toolName: "_notice_", summary: body });
|
|
21456
21743
|
log("best-effort surfaced unknown system subtype:", subtype ?? "?");
|
|
21457
21744
|
break;
|
|
@@ -21487,12 +21774,12 @@ ${text}` : header;
|
|
|
21487
21774
|
const tn = toolNameByUseId.get(toolUseId);
|
|
21488
21775
|
if (tn === "Edit" || tn === "Write" || tn === "MultiEdit" || tn === "NotebookEdit")
|
|
21489
21776
|
continue;
|
|
21490
|
-
const { text, truncated } = flattenToolResultContent(blk.content);
|
|
21777
|
+
const { text: text2, truncated } = flattenToolResultContent(blk.content);
|
|
21491
21778
|
const images = extractImages(blk.content);
|
|
21492
21779
|
const isError = blk.is_error === true;
|
|
21493
|
-
if (!
|
|
21780
|
+
if (!text2 && images.length === 0 && !isError)
|
|
21494
21781
|
continue;
|
|
21495
|
-
emit({ type: "agent:tool_result", sessionId: sid, toolUseId, isError, output:
|
|
21782
|
+
emit({ type: "agent:tool_result", sessionId: sid, toolUseId, isError, output: text2, images, truncated, ...agentId ? { agentId } : {} });
|
|
21496
21783
|
} else if (blk?.type === "web_search_tool_result") {
|
|
21497
21784
|
const toolUseId = blk.tool_use_id;
|
|
21498
21785
|
if (!toolUseId)
|
|
@@ -21509,11 +21796,11 @@ ${text}` : header;
|
|
|
21509
21796
|
break;
|
|
21510
21797
|
default: {
|
|
21511
21798
|
const m = message;
|
|
21512
|
-
const
|
|
21799
|
+
const text2 = extractHumanReadable(m);
|
|
21513
21800
|
const header = systemHeader(m.type || "unknown");
|
|
21514
|
-
const body =
|
|
21801
|
+
const body = text2 ? `${header}
|
|
21515
21802
|
|
|
21516
|
-
${
|
|
21803
|
+
${text2}` : header;
|
|
21517
21804
|
emit({ type: "agent:tool_use", sessionId: sid, toolName: "_notice_", summary: body });
|
|
21518
21805
|
log("best-effort surfaced unknown SDK message type:", m.type || "?");
|
|
21519
21806
|
break;
|
|
@@ -21818,6 +22105,8 @@ Element ${i + 1}:`);
|
|
|
21818
22105
|
parts.push(` XPath: ${a.xpath}`, ` CSS: ${a.selector}`, ` HTML: ${a.htmlSnippet}`);
|
|
21819
22106
|
if (a.textPreview)
|
|
21820
22107
|
parts.push(` Text: "${a.textPreview}"`);
|
|
22108
|
+
if (a.sourceLoc)
|
|
22109
|
+
parts.push(` Source: ${a.sourceLoc.file}:${a.sourceLoc.line}${a.sourceLoc.column != null ? `:${a.sourceLoc.column}` : ""} (edit the element here)`);
|
|
21821
22110
|
}
|
|
21822
22111
|
}
|
|
21823
22112
|
return parts.join("\n");
|
|
@@ -21830,15 +22119,23 @@ Element ${i + 1}:`);
|
|
|
21830
22119
|
var dist_exports = {};
|
|
21831
22120
|
__export(dist_exports, {
|
|
21832
22121
|
AgentManager: () => AgentManager,
|
|
22122
|
+
DESIGN_CLAUDE_MD: () => DESIGN_CLAUDE_MD,
|
|
22123
|
+
DESIGN_DIR: () => DESIGN_DIR,
|
|
22124
|
+
DesignTokensSchema: () => DesignTokensSchema,
|
|
21833
22125
|
SessionStore: () => SessionStore,
|
|
22126
|
+
TOKENS_CSS_FILE: () => TOKENS_CSS_FILE,
|
|
22127
|
+
TOKENS_FILE: () => TOKENS_FILE,
|
|
21834
22128
|
buildClaudeNarrationLlm: () => buildClaudeNarrationLlm,
|
|
21835
22129
|
exportSession: () => exportSession,
|
|
22130
|
+
getTokenPath: () => getTokenPath,
|
|
21836
22131
|
importSession: () => importSession,
|
|
21837
22132
|
log: () => log,
|
|
21838
22133
|
resolveOauthToken: () => resolveOauthToken,
|
|
21839
22134
|
sanitizeProjectDir: () => sanitizeProjectDir,
|
|
21840
22135
|
sessionDir: () => sessionDir,
|
|
21841
22136
|
sessionFile: () => sessionFile,
|
|
22137
|
+
setTokenPath: () => setTokenPath,
|
|
22138
|
+
tokensToCss: () => tokensToCss,
|
|
21842
22139
|
transferSession: () => transferSession
|
|
21843
22140
|
});
|
|
21844
22141
|
var init_dist2 = __esm({
|
|
@@ -21849,6 +22146,7 @@ var init_dist2 = __esm({
|
|
|
21849
22146
|
init_session_usage();
|
|
21850
22147
|
init_session_transfer();
|
|
21851
22148
|
init_log();
|
|
22149
|
+
init_design_tokens();
|
|
21852
22150
|
}
|
|
21853
22151
|
});
|
|
21854
22152
|
|
|
@@ -23056,11 +23354,11 @@ function __metadata(metadataKey, metadataValue) {
|
|
|
23056
23354
|
}
|
|
23057
23355
|
function __awaiter(thisArg, _arguments, P, generator) {
|
|
23058
23356
|
function adopt(value) {
|
|
23059
|
-
return value instanceof P ? value : new P(function(
|
|
23060
|
-
|
|
23357
|
+
return value instanceof P ? value : new P(function(resolve9) {
|
|
23358
|
+
resolve9(value);
|
|
23061
23359
|
});
|
|
23062
23360
|
}
|
|
23063
|
-
return new (P || (P = Promise))(function(
|
|
23361
|
+
return new (P || (P = Promise))(function(resolve9, reject) {
|
|
23064
23362
|
function fulfilled(value) {
|
|
23065
23363
|
try {
|
|
23066
23364
|
step(generator.next(value));
|
|
@@ -23076,7 +23374,7 @@ function __awaiter(thisArg, _arguments, P, generator) {
|
|
|
23076
23374
|
}
|
|
23077
23375
|
}
|
|
23078
23376
|
function step(result) {
|
|
23079
|
-
result.done ?
|
|
23377
|
+
result.done ? resolve9(result.value) : adopt(result.value).then(fulfilled, rejected);
|
|
23080
23378
|
}
|
|
23081
23379
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
23082
23380
|
});
|
|
@@ -23267,14 +23565,14 @@ function __asyncValues(o) {
|
|
|
23267
23565
|
}, i);
|
|
23268
23566
|
function verb(n) {
|
|
23269
23567
|
i[n] = o[n] && function(v) {
|
|
23270
|
-
return new Promise(function(
|
|
23271
|
-
v = o[n](v), settle(
|
|
23568
|
+
return new Promise(function(resolve9, reject) {
|
|
23569
|
+
v = o[n](v), settle(resolve9, reject, v.done, v.value);
|
|
23272
23570
|
});
|
|
23273
23571
|
};
|
|
23274
23572
|
}
|
|
23275
|
-
function settle(
|
|
23573
|
+
function settle(resolve9, reject, d, v) {
|
|
23276
23574
|
Promise.resolve(v).then(function(v2) {
|
|
23277
|
-
|
|
23575
|
+
resolve9({ value: v2, done: d });
|
|
23278
23576
|
}, reject);
|
|
23279
23577
|
}
|
|
23280
23578
|
}
|
|
@@ -23552,8 +23850,8 @@ var require_build = __commonJS({
|
|
|
23552
23850
|
var BASE64_REGEX = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/;
|
|
23553
23851
|
var BASE64URL_REGEX = /^[a-zA-Z0-9-_]+$/;
|
|
23554
23852
|
var Utf8Converter = class {
|
|
23555
|
-
static fromString(
|
|
23556
|
-
const s = unescape(encodeURIComponent(
|
|
23853
|
+
static fromString(text2) {
|
|
23854
|
+
const s = unescape(encodeURIComponent(text2));
|
|
23557
23855
|
const uintArray = new Uint8Array(s.length);
|
|
23558
23856
|
for (let i = 0; i < s.length; i++) {
|
|
23559
23857
|
uintArray[i] = s.charCodeAt(i);
|
|
@@ -23581,11 +23879,11 @@ var require_build = __commonJS({
|
|
|
23581
23879
|
}
|
|
23582
23880
|
return res;
|
|
23583
23881
|
}
|
|
23584
|
-
static fromString(
|
|
23585
|
-
const res = new ArrayBuffer(
|
|
23882
|
+
static fromString(text2, littleEndian = false) {
|
|
23883
|
+
const res = new ArrayBuffer(text2.length * 2);
|
|
23586
23884
|
const dataView = new DataView(res);
|
|
23587
|
-
for (let i = 0; i <
|
|
23588
|
-
dataView.setUint16(i * 2,
|
|
23885
|
+
for (let i = 0; i < text2.length; i++) {
|
|
23886
|
+
dataView.setUint16(i * 2, text2.charCodeAt(i), littleEndian);
|
|
23589
23887
|
}
|
|
23590
23888
|
return res;
|
|
23591
23889
|
}
|
|
@@ -23682,18 +23980,18 @@ var require_build = __commonJS({
|
|
|
23682
23980
|
static ToBase64Url(data) {
|
|
23683
23981
|
return this.ToBase64(data).replace(/\+/g, "-").replace(/\//g, "_").replace(/\=/g, "");
|
|
23684
23982
|
}
|
|
23685
|
-
static FromUtf8String(
|
|
23983
|
+
static FromUtf8String(text2, encoding = _Convert.DEFAULT_UTF8_ENCODING) {
|
|
23686
23984
|
switch (encoding) {
|
|
23687
23985
|
case "ascii":
|
|
23688
|
-
return this.FromBinary(
|
|
23986
|
+
return this.FromBinary(text2);
|
|
23689
23987
|
case "utf8":
|
|
23690
|
-
return Utf8Converter.fromString(
|
|
23988
|
+
return Utf8Converter.fromString(text2);
|
|
23691
23989
|
case "utf16":
|
|
23692
23990
|
case "utf16be":
|
|
23693
|
-
return Utf16Converter.fromString(
|
|
23991
|
+
return Utf16Converter.fromString(text2);
|
|
23694
23992
|
case "utf16le":
|
|
23695
23993
|
case "usc2":
|
|
23696
|
-
return Utf16Converter.fromString(
|
|
23994
|
+
return Utf16Converter.fromString(text2, true);
|
|
23697
23995
|
default:
|
|
23698
23996
|
throw new Error(`Unknown type of encoding '${encoding}'`);
|
|
23699
23997
|
}
|
|
@@ -23714,11 +24012,11 @@ var require_build = __commonJS({
|
|
|
23714
24012
|
throw new Error(`Unknown type of encoding '${encoding}'`);
|
|
23715
24013
|
}
|
|
23716
24014
|
}
|
|
23717
|
-
static FromBinary(
|
|
23718
|
-
const stringLength =
|
|
24015
|
+
static FromBinary(text2) {
|
|
24016
|
+
const stringLength = text2.length;
|
|
23719
24017
|
const resultView = new Uint8Array(stringLength);
|
|
23720
24018
|
for (let i = 0; i < stringLength; i++) {
|
|
23721
|
-
resultView[i] =
|
|
24019
|
+
resultView[i] = text2.charCodeAt(i);
|
|
23722
24020
|
}
|
|
23723
24021
|
return resultView.buffer;
|
|
23724
24022
|
}
|
|
@@ -23764,8 +24062,8 @@ var require_build = __commonJS({
|
|
|
23764
24062
|
static ToUtf16String(buffer, littleEndian = false) {
|
|
23765
24063
|
return Utf16Converter.toString(buffer, littleEndian);
|
|
23766
24064
|
}
|
|
23767
|
-
static FromUtf16String(
|
|
23768
|
-
return Utf16Converter.fromString(
|
|
24065
|
+
static FromUtf16String(text2, littleEndian = false) {
|
|
24066
|
+
return Utf16Converter.fromString(text2, littleEndian);
|
|
23769
24067
|
}
|
|
23770
24068
|
static Base64Padding(base643) {
|
|
23771
24069
|
const padCount = 4 - base643.length % 4;
|
|
@@ -27526,15 +27824,15 @@ var require_sequence = __commonJS({
|
|
|
27526
27824
|
}
|
|
27527
27825
|
return normalized;
|
|
27528
27826
|
}
|
|
27529
|
-
function encodeAscii(
|
|
27530
|
-
const bytes = new Uint8Array(
|
|
27531
|
-
for (let i = 0; i <
|
|
27532
|
-
bytes[i] =
|
|
27827
|
+
function encodeAscii(text2) {
|
|
27828
|
+
const bytes = new Uint8Array(text2.length);
|
|
27829
|
+
for (let i = 0; i < text2.length; i++) {
|
|
27830
|
+
bytes[i] = text2.charCodeAt(i) & 255;
|
|
27533
27831
|
}
|
|
27534
27832
|
return bytes;
|
|
27535
27833
|
}
|
|
27536
|
-
function encodeUtf8(
|
|
27537
|
-
return new TextEncoder().encode(
|
|
27834
|
+
function encodeUtf8(text2) {
|
|
27835
|
+
return new TextEncoder().encode(text2);
|
|
27538
27836
|
}
|
|
27539
27837
|
function toPatternBytes(pattern, options) {
|
|
27540
27838
|
if (typeof pattern === "string") {
|
|
@@ -28909,15 +29207,15 @@ var require_binary = __commonJS({
|
|
|
28909
29207
|
}
|
|
28910
29208
|
return result;
|
|
28911
29209
|
}
|
|
28912
|
-
function decode3(
|
|
28913
|
-
const result = new Uint8Array(
|
|
28914
|
-
for (let i = 0; i <
|
|
28915
|
-
result[i] =
|
|
29210
|
+
function decode3(text2) {
|
|
29211
|
+
const result = new Uint8Array(text2.length);
|
|
29212
|
+
for (let i = 0; i < text2.length; i++) {
|
|
29213
|
+
result[i] = text2.charCodeAt(i) & 255;
|
|
28916
29214
|
}
|
|
28917
29215
|
return result;
|
|
28918
29216
|
}
|
|
28919
|
-
function is(
|
|
28920
|
-
return typeof
|
|
29217
|
+
function is(text2) {
|
|
29218
|
+
return typeof text2 === "string";
|
|
28921
29219
|
}
|
|
28922
29220
|
exports.binary = { encode: encode3, decode: decode3, is };
|
|
28923
29221
|
}
|
|
@@ -28952,31 +29250,31 @@ var require_hex = __commonJS({
|
|
|
28952
29250
|
throw new TypeError("Hex separators must be non-empty strings");
|
|
28953
29251
|
}
|
|
28954
29252
|
}
|
|
28955
|
-
function matchSeparator(
|
|
29253
|
+
function matchSeparator(text2, index, separators) {
|
|
28956
29254
|
for (const separator of separators) {
|
|
28957
|
-
if (
|
|
29255
|
+
if (text2.startsWith(separator, index)) {
|
|
28958
29256
|
return separator;
|
|
28959
29257
|
}
|
|
28960
29258
|
}
|
|
28961
29259
|
return void 0;
|
|
28962
29260
|
}
|
|
28963
|
-
function detectCase(
|
|
28964
|
-
const hasUpper = /[A-F]/.test(
|
|
28965
|
-
const hasLower = /[a-f]/.test(
|
|
29261
|
+
function detectCase(text2) {
|
|
29262
|
+
const hasUpper = /[A-F]/.test(text2);
|
|
29263
|
+
const hasLower = /[a-f]/.test(text2);
|
|
28966
29264
|
return hasUpper && !hasLower ? "upper" : "lower";
|
|
28967
29265
|
}
|
|
28968
|
-
function detectLineSeparator(
|
|
28969
|
-
const match = /\r\n|\n/.exec(
|
|
29266
|
+
function detectLineSeparator(text2) {
|
|
29267
|
+
const match = /\r\n|\n/.exec(text2);
|
|
28970
29268
|
if (!match) {
|
|
28971
29269
|
return void 0;
|
|
28972
29270
|
}
|
|
28973
29271
|
return match[0] === "\r\n" ? "\r\n" : "\n";
|
|
28974
29272
|
}
|
|
28975
|
-
function compactForDetection(
|
|
28976
|
-
return
|
|
29273
|
+
function compactForDetection(text2) {
|
|
29274
|
+
return text2.replace(/[^0-9a-f]/gi, "");
|
|
28977
29275
|
}
|
|
28978
|
-
function detectGroup(
|
|
28979
|
-
const segments =
|
|
29276
|
+
function detectGroup(text2) {
|
|
29277
|
+
const segments = text2.match(/[0-9A-Fa-f]+|[^0-9A-Fa-f]+/g) ?? [];
|
|
28980
29278
|
if (segments.length < 3) {
|
|
28981
29279
|
return void 0;
|
|
28982
29280
|
}
|
|
@@ -29004,8 +29302,8 @@ var require_hex = __commonJS({
|
|
|
29004
29302
|
separator
|
|
29005
29303
|
};
|
|
29006
29304
|
}
|
|
29007
|
-
function detectFormat(
|
|
29008
|
-
const trimmed =
|
|
29305
|
+
function detectFormat(text2) {
|
|
29306
|
+
const trimmed = text2.trim();
|
|
29009
29307
|
const prefix = /^0x/i.test(trimmed) ? "0x" : "";
|
|
29010
29308
|
const body = prefix ? trimmed.slice(2) : trimmed;
|
|
29011
29309
|
const lineSeparator = detectLineSeparator(body);
|
|
@@ -29030,13 +29328,13 @@ var require_hex = __commonJS({
|
|
|
29030
29328
|
}
|
|
29031
29329
|
return format2;
|
|
29032
29330
|
}
|
|
29033
|
-
function normalizeText(
|
|
29331
|
+
function normalizeText(text2, options) {
|
|
29034
29332
|
const allowPrefix = options.allowPrefix ?? true;
|
|
29035
29333
|
const separators = [...resolveSeparators(options)].sort((left, right) => right.length - left.length);
|
|
29036
29334
|
for (const separator of separators) {
|
|
29037
29335
|
validateSeparator(separator);
|
|
29038
29336
|
}
|
|
29039
|
-
let working =
|
|
29337
|
+
let working = text2.trim();
|
|
29040
29338
|
if (/^0x/i.test(working)) {
|
|
29041
29339
|
if (!allowPrefix) {
|
|
29042
29340
|
throw new TypeError("Hexadecimal text must not include a 0x prefix");
|
|
@@ -29087,15 +29385,15 @@ var require_hex = __commonJS({
|
|
|
29087
29385
|
}
|
|
29088
29386
|
return chunks.join(group.separator);
|
|
29089
29387
|
}
|
|
29090
|
-
function normalize2(
|
|
29091
|
-
return normalizeText(
|
|
29388
|
+
function normalize2(text2, options = {}) {
|
|
29389
|
+
return normalizeText(text2, options);
|
|
29092
29390
|
}
|
|
29093
|
-
function is(
|
|
29094
|
-
if (typeof
|
|
29391
|
+
function is(text2, options = {}) {
|
|
29392
|
+
if (typeof text2 !== "string") {
|
|
29095
29393
|
return false;
|
|
29096
29394
|
}
|
|
29097
29395
|
try {
|
|
29098
|
-
normalize2(
|
|
29396
|
+
normalize2(text2, options);
|
|
29099
29397
|
return true;
|
|
29100
29398
|
} catch {
|
|
29101
29399
|
return false;
|
|
@@ -29105,8 +29403,8 @@ var require_hex = __commonJS({
|
|
|
29105
29403
|
const bytes = (0, index_js_1.toUint8Array)(data);
|
|
29106
29404
|
const casing = options.case ?? "lower";
|
|
29107
29405
|
const pairs = Array.from(bytes, (byte) => {
|
|
29108
|
-
const
|
|
29109
|
-
return casing === "upper" ?
|
|
29406
|
+
const text2 = byte.toString(16).padStart(2, "0");
|
|
29407
|
+
return casing === "upper" ? text2.toUpperCase() : text2;
|
|
29110
29408
|
});
|
|
29111
29409
|
let body = "";
|
|
29112
29410
|
if (options.line) {
|
|
@@ -29125,19 +29423,19 @@ var require_hex = __commonJS({
|
|
|
29125
29423
|
}
|
|
29126
29424
|
return `${options.prefix ?? ""}${body}`;
|
|
29127
29425
|
}
|
|
29128
|
-
function decode3(
|
|
29129
|
-
const normalized = normalize2(
|
|
29426
|
+
function decode3(text2, options = {}) {
|
|
29427
|
+
const normalized = normalize2(text2, options);
|
|
29130
29428
|
const result = new Uint8Array(normalized.length / 2);
|
|
29131
29429
|
for (let i = 0; i < normalized.length; i += 2) {
|
|
29132
29430
|
result[i / 2] = Number.parseInt(normalized.slice(i, i + 2), 16);
|
|
29133
29431
|
}
|
|
29134
29432
|
return result;
|
|
29135
29433
|
}
|
|
29136
|
-
function parse3(
|
|
29137
|
-
const normalized = normalize2(
|
|
29434
|
+
function parse3(text2, options = {}) {
|
|
29435
|
+
const normalized = normalize2(text2, options);
|
|
29138
29436
|
return {
|
|
29139
29437
|
bytes: decode3(normalized),
|
|
29140
|
-
format: detectFormat(
|
|
29438
|
+
format: detectFormat(text2),
|
|
29141
29439
|
normalized
|
|
29142
29440
|
};
|
|
29143
29441
|
}
|
|
@@ -29165,8 +29463,8 @@ var require_utf8 = __commonJS({
|
|
|
29165
29463
|
exports.encode = encode3;
|
|
29166
29464
|
exports.decode = decode3;
|
|
29167
29465
|
var index_js_1 = require_bytes();
|
|
29168
|
-
function encode3(
|
|
29169
|
-
return new TextEncoder().encode(
|
|
29466
|
+
function encode3(text2) {
|
|
29467
|
+
return new TextEncoder().encode(text2);
|
|
29170
29468
|
}
|
|
29171
29469
|
function decode3(data) {
|
|
29172
29470
|
return new TextDecoder("utf-8", { fatal: false }).decode((0, index_js_1.toUint8Array)(data));
|
|
@@ -29184,11 +29482,11 @@ var require_utf16 = __commonJS({
|
|
|
29184
29482
|
exports.encode = encode3;
|
|
29185
29483
|
exports.decode = decode3;
|
|
29186
29484
|
var index_js_1 = require_bytes();
|
|
29187
|
-
function encode3(
|
|
29188
|
-
const result = new ArrayBuffer(
|
|
29485
|
+
function encode3(text2, options = {}) {
|
|
29486
|
+
const result = new ArrayBuffer(text2.length * 2);
|
|
29189
29487
|
const view = new DataView(result);
|
|
29190
|
-
for (let i = 0; i <
|
|
29191
|
-
view.setUint16(i * 2,
|
|
29488
|
+
for (let i = 0; i < text2.length; i++) {
|
|
29489
|
+
view.setUint16(i * 2, text2.charCodeAt(i), options.littleEndian ?? false);
|
|
29192
29490
|
}
|
|
29193
29491
|
return new Uint8Array(result);
|
|
29194
29492
|
}
|
|
@@ -29222,18 +29520,18 @@ var require_base64 = __commonJS({
|
|
|
29222
29520
|
function nodeBuffer() {
|
|
29223
29521
|
return globalThis.Buffer;
|
|
29224
29522
|
}
|
|
29225
|
-
function normalize2(
|
|
29226
|
-
return
|
|
29523
|
+
function normalize2(text2) {
|
|
29524
|
+
return text2.replace(/[\n\r\t ]/g, "");
|
|
29227
29525
|
}
|
|
29228
|
-
function pad(
|
|
29229
|
-
const remainder =
|
|
29230
|
-
return remainder ?
|
|
29526
|
+
function pad(text2) {
|
|
29527
|
+
const remainder = text2.length % 4;
|
|
29528
|
+
return remainder ? text2 + "=".repeat(4 - remainder) : text2;
|
|
29231
29529
|
}
|
|
29232
|
-
function is(
|
|
29233
|
-
if (typeof
|
|
29530
|
+
function is(text2) {
|
|
29531
|
+
if (typeof text2 !== "string") {
|
|
29234
29532
|
return false;
|
|
29235
29533
|
}
|
|
29236
|
-
const normalized = normalize2(
|
|
29534
|
+
const normalized = normalize2(text2);
|
|
29237
29535
|
return normalized === "" || BASE64_REGEX.test(normalized);
|
|
29238
29536
|
}
|
|
29239
29537
|
function encode3(data, _options) {
|
|
@@ -29244,8 +29542,8 @@ var require_base64 = __commonJS({
|
|
|
29244
29542
|
}
|
|
29245
29543
|
return btoa((0, binary_js_1.encode)(bytes));
|
|
29246
29544
|
}
|
|
29247
|
-
function decode3(
|
|
29248
|
-
const normalized = normalize2(
|
|
29545
|
+
function decode3(text2, _options) {
|
|
29546
|
+
const normalized = normalize2(text2);
|
|
29249
29547
|
if (!is(normalized)) {
|
|
29250
29548
|
throw new TypeError("Input is not valid Base64 text");
|
|
29251
29549
|
}
|
|
@@ -29271,17 +29569,17 @@ var require_base64url = __commonJS({
|
|
|
29271
29569
|
exports.decode = decode3;
|
|
29272
29570
|
var base64_js_1 = require_base64();
|
|
29273
29571
|
var BASE64URL_REGEX = /^[A-Za-z0-9_-]*$/;
|
|
29274
|
-
function normalize2(
|
|
29275
|
-
return
|
|
29572
|
+
function normalize2(text2) {
|
|
29573
|
+
return text2.replace(/[\n\r\t ]/g, "");
|
|
29276
29574
|
}
|
|
29277
|
-
function is(
|
|
29278
|
-
return typeof
|
|
29575
|
+
function is(text2) {
|
|
29576
|
+
return typeof text2 === "string" && BASE64URL_REGEX.test(normalize2(text2));
|
|
29279
29577
|
}
|
|
29280
29578
|
function encode3(data, _options) {
|
|
29281
29579
|
return base64_js_1.base64.encode(data).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, "");
|
|
29282
29580
|
}
|
|
29283
|
-
function decode3(
|
|
29284
|
-
const normalized = normalize2(
|
|
29581
|
+
function decode3(text2, _options) {
|
|
29582
|
+
const normalized = normalize2(text2);
|
|
29285
29583
|
if (!is(normalized)) {
|
|
29286
29584
|
throw new TypeError("Input is not valid Base64Url text");
|
|
29287
29585
|
}
|
|
@@ -29402,8 +29700,8 @@ var require_ip_converter = __commonJS({
|
|
|
29402
29700
|
}
|
|
29403
29701
|
return ip;
|
|
29404
29702
|
}
|
|
29405
|
-
static parseCIDR(
|
|
29406
|
-
const [addr, prefixStr] =
|
|
29703
|
+
static parseCIDR(text2) {
|
|
29704
|
+
const [addr, prefixStr] = text2.split("/");
|
|
29407
29705
|
const prefix = parseInt(prefixStr, 10);
|
|
29408
29706
|
if (this.isIPv4(addr)) {
|
|
29409
29707
|
if (prefix < 0 || prefix > 32) {
|
|
@@ -29456,9 +29754,9 @@ var require_ip_converter = __commonJS({
|
|
|
29456
29754
|
}
|
|
29457
29755
|
return this.decodeIP(encoding_1.hex.encode(buf));
|
|
29458
29756
|
}
|
|
29459
|
-
static fromString(
|
|
29460
|
-
if (
|
|
29461
|
-
const [addr, prefix] = this.parseCIDR(
|
|
29757
|
+
static fromString(text2) {
|
|
29758
|
+
if (text2.includes("/")) {
|
|
29759
|
+
const [addr, prefix] = this.parseCIDR(text2);
|
|
29462
29760
|
const maskBytes = new Uint8Array(addr.length);
|
|
29463
29761
|
let bitsLeft = prefix;
|
|
29464
29762
|
for (let i = 0; i < maskBytes.length; i++) {
|
|
@@ -29475,7 +29773,7 @@ var require_ip_converter = __commonJS({
|
|
|
29475
29773
|
out.set(maskBytes, addr.length);
|
|
29476
29774
|
return out.buffer;
|
|
29477
29775
|
}
|
|
29478
|
-
const bytes = this.isIPv4(
|
|
29776
|
+
const bytes = this.isIPv4(text2) ? this.parseIPv4(text2) : this.parseIPv6(text2);
|
|
29479
29777
|
return new Uint8Array(bytes).buffer;
|
|
29480
29778
|
}
|
|
29481
29779
|
};
|
|
@@ -34286,11 +34584,11 @@ function __metadata2(metadataKey, metadataValue) {
|
|
|
34286
34584
|
}
|
|
34287
34585
|
function __awaiter2(thisArg, _arguments, P, generator) {
|
|
34288
34586
|
function adopt(value) {
|
|
34289
|
-
return value instanceof P ? value : new P(function(
|
|
34290
|
-
|
|
34587
|
+
return value instanceof P ? value : new P(function(resolve9) {
|
|
34588
|
+
resolve9(value);
|
|
34291
34589
|
});
|
|
34292
34590
|
}
|
|
34293
|
-
return new (P || (P = Promise))(function(
|
|
34591
|
+
return new (P || (P = Promise))(function(resolve9, reject) {
|
|
34294
34592
|
function fulfilled(value) {
|
|
34295
34593
|
try {
|
|
34296
34594
|
step(generator.next(value));
|
|
@@ -34306,7 +34604,7 @@ function __awaiter2(thisArg, _arguments, P, generator) {
|
|
|
34306
34604
|
}
|
|
34307
34605
|
}
|
|
34308
34606
|
function step(result) {
|
|
34309
|
-
result.done ?
|
|
34607
|
+
result.done ? resolve9(result.value) : adopt(result.value).then(fulfilled, rejected);
|
|
34310
34608
|
}
|
|
34311
34609
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
34312
34610
|
});
|
|
@@ -34484,14 +34782,14 @@ function __asyncValues2(o) {
|
|
|
34484
34782
|
}, i);
|
|
34485
34783
|
function verb(n) {
|
|
34486
34784
|
i[n] = o[n] && function(v) {
|
|
34487
|
-
return new Promise(function(
|
|
34488
|
-
v = o[n](v), settle(
|
|
34785
|
+
return new Promise(function(resolve9, reject) {
|
|
34786
|
+
v = o[n](v), settle(resolve9, reject, v.done, v.value);
|
|
34489
34787
|
});
|
|
34490
34788
|
};
|
|
34491
34789
|
}
|
|
34492
|
-
function settle(
|
|
34790
|
+
function settle(resolve9, reject, d, v) {
|
|
34493
34791
|
Promise.resolve(v).then(function(v2) {
|
|
34494
|
-
|
|
34792
|
+
resolve9({ value: v2, done: d });
|
|
34495
34793
|
}, reject);
|
|
34496
34794
|
}
|
|
34497
34795
|
}
|
|
@@ -37155,24 +37453,24 @@ var require_x509_cjs = __commonJS({
|
|
|
37155
37453
|
names.register("I", "2.5.4.43");
|
|
37156
37454
|
names.register("SN", "2.5.4.4");
|
|
37157
37455
|
names.register("T", "2.5.4.12");
|
|
37158
|
-
function replaceUnknownCharacter(
|
|
37456
|
+
function replaceUnknownCharacter(text2, char) {
|
|
37159
37457
|
return `\\${pvtsutils.Convert.ToHex(pvtsutils.Convert.FromUtf8String(char)).toUpperCase()}`;
|
|
37160
37458
|
}
|
|
37161
37459
|
function escape2(data) {
|
|
37162
37460
|
return data.replace(/([,+"\\<>;])/g, "\\$1").replace(/^([ #])/, "\\$1").replace(/([ ]$)/, "\\$1").replace(/([\r\n\t])/, replaceUnknownCharacter);
|
|
37163
37461
|
}
|
|
37164
37462
|
var Name = class _Name {
|
|
37165
|
-
static isASCII(
|
|
37166
|
-
for (let i = 0; i <
|
|
37167
|
-
const code =
|
|
37463
|
+
static isASCII(text2) {
|
|
37464
|
+
for (let i = 0; i < text2.length; i++) {
|
|
37465
|
+
const code = text2.charCodeAt(i);
|
|
37168
37466
|
if (code > 255) {
|
|
37169
37467
|
return false;
|
|
37170
37468
|
}
|
|
37171
37469
|
}
|
|
37172
37470
|
return true;
|
|
37173
37471
|
}
|
|
37174
|
-
static isPrintableString(
|
|
37175
|
-
return /^[A-Za-z0-9 '()+,-./:=?]*$/g.test(
|
|
37472
|
+
static isPrintableString(text2) {
|
|
37473
|
+
return /^[A-Za-z0-9 '()+,-./:=?]*$/g.test(text2);
|
|
37176
37474
|
}
|
|
37177
37475
|
constructor(data, extraNames = {}) {
|
|
37178
37476
|
this.extraNames = new NameIdentifier();
|
|
@@ -40394,7 +40692,6 @@ var init_stun = __esm({
|
|
|
40394
40692
|
// ../../packages/host-core/dist/peer-link/quic-transport.js
|
|
40395
40693
|
var quic_transport_exports = {};
|
|
40396
40694
|
__export(quic_transport_exports, {
|
|
40397
|
-
QUIC_ENABLED: () => QUIC_ENABLED,
|
|
40398
40695
|
discoverSrflx: () => discoverSrflx,
|
|
40399
40696
|
makeQuicSocket: () => makeQuicSocket,
|
|
40400
40697
|
nudgePunch: () => nudgePunch,
|
|
@@ -40404,7 +40701,6 @@ __export(quic_transport_exports, {
|
|
|
40404
40701
|
import { webcrypto } from "node:crypto";
|
|
40405
40702
|
import { createHmac } from "node:crypto";
|
|
40406
40703
|
import { EventEmitter } from "node:events";
|
|
40407
|
-
import { QUICClient, QUICServer, QUICSocket, events as quicEvents } from "@matrixai/quic";
|
|
40408
40704
|
function serverCrypto() {
|
|
40409
40705
|
const key2 = webcrypto.getRandomValues(new Uint8Array(32));
|
|
40410
40706
|
return {
|
|
@@ -40487,12 +40783,14 @@ function pinningVerify(expectedFingerprint256) {
|
|
|
40487
40783
|
};
|
|
40488
40784
|
}
|
|
40489
40785
|
async function makeQuicSocket(localPort) {
|
|
40490
|
-
const
|
|
40786
|
+
const { QUICSocket: QUICSocketCtor } = await loadQuic();
|
|
40787
|
+
const socket2 = new QUICSocketCtor({});
|
|
40491
40788
|
await socket2.start({ host: "0.0.0.0", port: localPort, reuseAddr: true });
|
|
40492
40789
|
return socket2;
|
|
40493
40790
|
}
|
|
40494
40791
|
async function quicDialLink(opts) {
|
|
40495
|
-
const
|
|
40792
|
+
const { QUICClient: QUICClientCtor } = await loadQuic();
|
|
40793
|
+
const client = await QUICClientCtor.createQUICClient({
|
|
40496
40794
|
socket: opts.socket,
|
|
40497
40795
|
host: opts.host,
|
|
40498
40796
|
port: opts.port,
|
|
@@ -40505,7 +40803,8 @@ async function quicDialLink(opts) {
|
|
|
40505
40803
|
return link;
|
|
40506
40804
|
}
|
|
40507
40805
|
async function startQuicServerOnSocket(opts) {
|
|
40508
|
-
const
|
|
40806
|
+
const { QUICServer: QUICServerCtor, events: quicEvents } = await loadQuic();
|
|
40807
|
+
const server = new QUICServerCtor({
|
|
40509
40808
|
crypto: serverCrypto(),
|
|
40510
40809
|
config: { applicationProtos: ALPN, key: opts.identity.key, cert: opts.identity.cert, verifyPeer: false },
|
|
40511
40810
|
socket: opts.socket
|
|
@@ -40523,7 +40822,7 @@ async function startQuicServerOnSocket(opts) {
|
|
|
40523
40822
|
function discoverSrflx(socket2, stunHost, stunPort, timeoutMs = 3e3) {
|
|
40524
40823
|
const dgramSock = socket2.socket;
|
|
40525
40824
|
const { packet, txId } = encodeBindingRequest();
|
|
40526
|
-
return new Promise((
|
|
40825
|
+
return new Promise((resolve9, reject) => {
|
|
40527
40826
|
const timer = setTimeout(() => {
|
|
40528
40827
|
dgramSock.removeListener("message", onMsg);
|
|
40529
40828
|
reject(new Error("quic: STUN timeout"));
|
|
@@ -40533,7 +40832,7 @@ function discoverSrflx(socket2, stunHost, stunPort, timeoutMs = 3e3) {
|
|
|
40533
40832
|
if (mapped) {
|
|
40534
40833
|
clearTimeout(timer);
|
|
40535
40834
|
dgramSock.removeListener("message", onMsg);
|
|
40536
|
-
|
|
40835
|
+
resolve9(`${mapped.ip}:${mapped.port}`);
|
|
40537
40836
|
}
|
|
40538
40837
|
};
|
|
40539
40838
|
dgramSock.on("message", onMsg);
|
|
@@ -40554,14 +40853,15 @@ async function nudgePunch(socket2, peerIp, peerPort, count = 12, intervalMs = 10
|
|
|
40554
40853
|
await new Promise((r) => setTimeout(r, intervalMs));
|
|
40555
40854
|
}
|
|
40556
40855
|
}
|
|
40557
|
-
var
|
|
40856
|
+
var ALPN, quicModP, loadQuic, clientCrypto;
|
|
40558
40857
|
var init_quic_transport = __esm({
|
|
40559
40858
|
"../../packages/host-core/dist/peer-link/quic-transport.js"() {
|
|
40560
40859
|
"use strict";
|
|
40561
40860
|
init_transport();
|
|
40562
40861
|
init_stun();
|
|
40563
|
-
QUIC_ENABLED = process.env.CCB_P2P_QUIC === "1";
|
|
40564
40862
|
ALPN = ["tesseract-peer"];
|
|
40863
|
+
quicModP = null;
|
|
40864
|
+
loadQuic = () => quicModP ??= import("@matrixai/quic");
|
|
40565
40865
|
clientCrypto = {
|
|
40566
40866
|
ops: { randomBytes: async (data) => {
|
|
40567
40867
|
webcrypto.getRandomValues(new Uint8Array(data));
|
|
@@ -41641,17 +41941,17 @@ var require_main = __commonJS({
|
|
|
41641
41941
|
});
|
|
41642
41942
|
|
|
41643
41943
|
// src/cli.ts
|
|
41644
|
-
import { readFileSync as
|
|
41944
|
+
import { readFileSync as readFileSync13 } from "node:fs";
|
|
41645
41945
|
import { createHash as createHash5 } from "node:crypto";
|
|
41646
41946
|
import { spawn as spawn7 } from "node:child_process";
|
|
41647
41947
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
41648
41948
|
import { homedir as homedir14 } from "node:os";
|
|
41649
|
-
import { dirname as dirname16, join as
|
|
41949
|
+
import { dirname as dirname16, join as join33, resolve as resolve8 } from "node:path";
|
|
41650
41950
|
import { createInterface } from "node:readline/promises";
|
|
41651
41951
|
|
|
41652
41952
|
// ../../packages/host-core/dist/control-link.js
|
|
41653
41953
|
import { hostname as hostname3, homedir as homedir10 } from "node:os";
|
|
41654
|
-
import { join as
|
|
41954
|
+
import { join as join26, basename as basename5 } from "node:path";
|
|
41655
41955
|
import { mkdirSync as mkdirSync9 } from "node:fs";
|
|
41656
41956
|
|
|
41657
41957
|
// ../../node_modules/ws/wrapper.mjs
|
|
@@ -41699,7 +41999,7 @@ function isInsideRoot(p, root) {
|
|
|
41699
41999
|
}
|
|
41700
42000
|
|
|
41701
42001
|
// ../../packages/host-core/dist/daemon-agent.js
|
|
41702
|
-
import { join as
|
|
42002
|
+
import { join as join15 } from "node:path";
|
|
41703
42003
|
|
|
41704
42004
|
// ../../packages/host-core/dist/agent-backend.js
|
|
41705
42005
|
async function createClaudeCodeBackend(send2, onBrowserRequest, loadPluginRuntime2) {
|
|
@@ -41768,10 +42068,10 @@ var CliAgentBackend = class {
|
|
|
41768
42068
|
id;
|
|
41769
42069
|
capabilities;
|
|
41770
42070
|
live = /* @__PURE__ */ new Map();
|
|
41771
|
-
constructor(adapter, send2,
|
|
42071
|
+
constructor(adapter, send2, resolve9) {
|
|
41772
42072
|
this.adapter = adapter;
|
|
41773
42073
|
this.send = send2;
|
|
41774
|
-
this.resolve =
|
|
42074
|
+
this.resolve = resolve9;
|
|
41775
42075
|
this.id = adapter.id;
|
|
41776
42076
|
this.capabilities = adapter.capabilities;
|
|
41777
42077
|
}
|
|
@@ -42039,9 +42339,9 @@ var geminiAdapter = {
|
|
|
42039
42339
|
},
|
|
42040
42340
|
translate(event, raw, emit, ctx) {
|
|
42041
42341
|
const o = asObj3(event);
|
|
42042
|
-
const
|
|
42043
|
-
if (
|
|
42044
|
-
emit({ type: "chat:stream", sessionId: ctx.sessionId, clientRequestId: ctx.clientRequestId, delta:
|
|
42342
|
+
const text2 = o ? typeof o.response === "string" ? o.response : bestEffortText(o) : typeof event === "string" ? event : raw;
|
|
42343
|
+
if (text2)
|
|
42344
|
+
emit({ type: "chat:stream", sessionId: ctx.sessionId, clientRequestId: ctx.clientRequestId, delta: text2, messageId: ctx.messageId, kind: "text" });
|
|
42045
42345
|
const tools = o?.tools;
|
|
42046
42346
|
if (Array.isArray(tools)) {
|
|
42047
42347
|
for (const t of tools) {
|
|
@@ -42067,25 +42367,25 @@ var openclawAdapter = {
|
|
|
42067
42367
|
translate(event, raw, emit, ctx) {
|
|
42068
42368
|
const o = asObj4(event);
|
|
42069
42369
|
const result = asObj4(o?.result) ?? o;
|
|
42070
|
-
let
|
|
42370
|
+
let text2 = "";
|
|
42071
42371
|
const payloads = result?.payloads;
|
|
42072
42372
|
if (Array.isArray(payloads)) {
|
|
42073
|
-
|
|
42373
|
+
text2 = payloads.map((p) => {
|
|
42074
42374
|
const t = asObj4(p)?.text;
|
|
42075
42375
|
return typeof t === "string" ? t : "";
|
|
42076
42376
|
}).filter(Boolean).join("\n");
|
|
42077
42377
|
}
|
|
42078
|
-
if (!
|
|
42378
|
+
if (!text2) {
|
|
42079
42379
|
const fav = asObj4(result?.meta)?.finalAssistantVisibleText;
|
|
42080
42380
|
if (typeof fav === "string")
|
|
42081
|
-
|
|
42381
|
+
text2 = fav;
|
|
42082
42382
|
}
|
|
42083
|
-
if (!
|
|
42084
|
-
|
|
42085
|
-
if (
|
|
42086
|
-
emit({ type: "chat:stream", sessionId: ctx.sessionId, clientRequestId: ctx.clientRequestId, delta:
|
|
42383
|
+
if (!text2)
|
|
42384
|
+
text2 = o ? bestEffortText(result ?? o) : typeof event === "string" ? event : raw;
|
|
42385
|
+
if (text2)
|
|
42386
|
+
emit({ type: "chat:stream", sessionId: ctx.sessionId, clientRequestId: ctx.clientRequestId, delta: text2, messageId: ctx.messageId, kind: "text" });
|
|
42087
42387
|
const status2 = typeof o?.status === "string" ? o.status : void 0;
|
|
42088
|
-
if (!
|
|
42388
|
+
if (!text2 && status2 && status2 !== "ok" && status2 !== "accepted") {
|
|
42089
42389
|
const summary = typeof o?.summary === "string" && o.summary ? o.summary : `OpenClaw run ${status2}.`;
|
|
42090
42390
|
emit({ type: "chat:error", sessionId: ctx.sessionId, clientRequestId: ctx.clientRequestId, error: summary });
|
|
42091
42391
|
}
|
|
@@ -42133,7 +42433,7 @@ init_dist2();
|
|
|
42133
42433
|
|
|
42134
42434
|
// ../../packages/host-core/dist/plugin-tools.js
|
|
42135
42435
|
import { existsSync as existsSync3 } from "node:fs";
|
|
42136
|
-
import { join as
|
|
42436
|
+
import { join as join8 } from "node:path";
|
|
42137
42437
|
|
|
42138
42438
|
// ../../packages/plugin-host/dist/discovery.js
|
|
42139
42439
|
import fs2 from "node:fs";
|
|
@@ -42303,8 +42603,8 @@ function createOpenClawAdapter(pluginId, config2, secretResolver, registry2) {
|
|
|
42303
42603
|
pluginId,
|
|
42304
42604
|
config: config2,
|
|
42305
42605
|
secret: (envKey2) => secretResolver(pluginId, envKey2),
|
|
42306
|
-
registerTool: (
|
|
42307
|
-
const got = typeof
|
|
42606
|
+
registerTool: (tool3) => {
|
|
42607
|
+
const got = typeof tool3 === "function" ? tool3({}) : tool3;
|
|
42308
42608
|
const arr = Array.isArray(got) ? got : got ? [got] : [];
|
|
42309
42609
|
for (const t of arr) {
|
|
42310
42610
|
const c = convertTool(t);
|
|
@@ -42373,10 +42673,10 @@ var HostPluginApi = class {
|
|
|
42373
42673
|
secret(envKey2) {
|
|
42374
42674
|
return this.secretResolver(this.pluginId, envKey2);
|
|
42375
42675
|
}
|
|
42376
|
-
registerTool(
|
|
42676
|
+
registerTool(tool3) {
|
|
42377
42677
|
const prefix = this.pluginId.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
42378
|
-
const name =
|
|
42379
|
-
this.registry.tools.push({ ...
|
|
42678
|
+
const name = tool3.name.startsWith(`${prefix}_`) ? tool3.name : `${prefix}_${tool3.name}`;
|
|
42679
|
+
this.registry.tools.push({ ...tool3, name });
|
|
42380
42680
|
}
|
|
42381
42681
|
registerHook(reg) {
|
|
42382
42682
|
this.registry.hooks.push(reg);
|
|
@@ -42481,7 +42781,7 @@ async function loadPluginRuntime(opts) {
|
|
|
42481
42781
|
}
|
|
42482
42782
|
function buildDaemonPluginLoader(pluginsDir) {
|
|
42483
42783
|
return async () => {
|
|
42484
|
-
const scan =
|
|
42784
|
+
const scan = join8(pluginsDir, "node_modules");
|
|
42485
42785
|
if (!existsSync3(scan))
|
|
42486
42786
|
return { tools: [], hooks: [], engines: [] };
|
|
42487
42787
|
writeOpenClawShim(pluginsDir);
|
|
@@ -42493,18 +42793,18 @@ function buildDaemonPluginLoader(pluginsDir) {
|
|
|
42493
42793
|
}
|
|
42494
42794
|
|
|
42495
42795
|
// ../../packages/host-core/dist/credentials.js
|
|
42496
|
-
import { readFileSync as
|
|
42497
|
-
import { join as
|
|
42796
|
+
import { readFileSync as readFileSync4, writeFileSync as writeFileSync3, mkdirSync as mkdirSync2, existsSync as existsSync4, renameSync as renameSync3, chmodSync } from "node:fs";
|
|
42797
|
+
import { join as join9 } from "node:path";
|
|
42498
42798
|
import { homedir as homedir3 } from "node:os";
|
|
42499
42799
|
function daemonDir() {
|
|
42500
|
-
return process.env.CCB_DAEMON_DIR ??
|
|
42800
|
+
return process.env.CCB_DAEMON_DIR ?? join9(homedir3(), ".tesseract", "daemon");
|
|
42501
42801
|
}
|
|
42502
42802
|
function credentialsPath() {
|
|
42503
|
-
return
|
|
42803
|
+
return join9(daemonDir(), "credentials.json");
|
|
42504
42804
|
}
|
|
42505
42805
|
function readCredentials() {
|
|
42506
42806
|
try {
|
|
42507
|
-
const c = JSON.parse(
|
|
42807
|
+
const c = JSON.parse(readFileSync4(credentialsPath(), "utf-8"));
|
|
42508
42808
|
if (c.accessToken && c.refreshSecret && c.dtid && c.deviceId && c.userId && c.backendOrigin && c.apiOrigin) {
|
|
42509
42809
|
return c;
|
|
42510
42810
|
}
|
|
@@ -42808,13 +43108,13 @@ async function closeEnginePage(browserId) {
|
|
|
42808
43108
|
}
|
|
42809
43109
|
|
|
42810
43110
|
// ../../packages/host-core/dist/daemon-settings.js
|
|
42811
|
-
import { readFileSync as
|
|
42812
|
-
import { join as
|
|
43111
|
+
import { readFileSync as readFileSync7 } from "node:fs";
|
|
43112
|
+
import { join as join14 } from "node:path";
|
|
42813
43113
|
|
|
42814
43114
|
// ../../packages/host-core/dist/runners/resolve.js
|
|
42815
|
-
import { readFileSync as
|
|
43115
|
+
import { readFileSync as readFileSync5, existsSync as existsSync6, statSync, mkdirSync as mkdirSync4, writeFileSync as writeFileSync5 } from "node:fs";
|
|
42816
43116
|
import { homedir as homedir5 } from "node:os";
|
|
42817
|
-
import { join as
|
|
43117
|
+
import { join as join11 } from "node:path";
|
|
42818
43118
|
import { createHash as createHash2 } from "node:crypto";
|
|
42819
43119
|
|
|
42820
43120
|
// ../../packages/shared/dist/ws-protocol.js
|
|
@@ -42837,6 +43137,8 @@ var MIRRORED_AGENT_EVENTS = /* @__PURE__ */ new Set([
|
|
|
42837
43137
|
// plan review — co-viewers see the sectioned plan
|
|
42838
43138
|
"agent:narration",
|
|
42839
43139
|
// live status strip — co-viewers see "what it's doing now"
|
|
43140
|
+
"agent:preview_ready",
|
|
43141
|
+
// co-viewers (incl. mobile) see the preview the moment it's ready
|
|
42840
43142
|
"agent:elicitation_complete",
|
|
42841
43143
|
// M5 — co-viewers clear a resolved url-mode card
|
|
42842
43144
|
"chat:echoed",
|
|
@@ -43286,22 +43588,22 @@ import { createRequire as createRequire2 } from "node:module";
|
|
|
43286
43588
|
import { randomUUID as randomUUID4, createHash } from "node:crypto";
|
|
43287
43589
|
import { existsSync as existsSync5, mkdirSync as mkdirSync3, writeFileSync as writeFileSync4 } from "node:fs";
|
|
43288
43590
|
import { homedir as homedir4 } from "node:os";
|
|
43289
|
-
import { join as
|
|
43591
|
+
import { join as join10, dirname as dirname5, sep as sep2 } from "node:path";
|
|
43290
43592
|
import { request as httpRequest } from "node:http";
|
|
43291
43593
|
var requireFromHere = createRequire2(import.meta.url);
|
|
43292
43594
|
var ROUTER_PORT = 8787;
|
|
43293
43595
|
var BIND_HOST = "127.0.0.1";
|
|
43294
43596
|
var ROUTER_TOKEN = randomUUID4();
|
|
43295
|
-
var routerHomeDir =
|
|
43597
|
+
var routerHomeDir = join10(homedir4(), ".tesseract", "router-home");
|
|
43296
43598
|
var lastConfigHash = "";
|
|
43297
43599
|
var running = false;
|
|
43298
43600
|
var starting = null;
|
|
43299
43601
|
function configPath() {
|
|
43300
|
-
return
|
|
43602
|
+
return join10(routerHomeDir, ".claude-code-router", "config.json");
|
|
43301
43603
|
}
|
|
43302
43604
|
function ccrCliPath() {
|
|
43303
43605
|
const pkg = requireFromHere.resolve("@musistudio/claude-code-router/package.json");
|
|
43304
|
-
const cli =
|
|
43606
|
+
const cli = join10(dirname5(pkg), "dist", "cli.js");
|
|
43305
43607
|
return cli.replace(`app.asar${sep2}`, `app.asar.unpacked${sep2}`);
|
|
43306
43608
|
}
|
|
43307
43609
|
var cachedNodeExe2;
|
|
@@ -43391,39 +43693,39 @@ function buildRouterConfig(d) {
|
|
|
43391
43693
|
};
|
|
43392
43694
|
}
|
|
43393
43695
|
function writeConfig(cfg2) {
|
|
43394
|
-
const dir =
|
|
43696
|
+
const dir = join10(routerHomeDir, ".claude-code-router");
|
|
43395
43697
|
if (!existsSync5(dir))
|
|
43396
43698
|
mkdirSync3(dir, { recursive: true });
|
|
43397
43699
|
writeFileSync4(configPath(), JSON.stringify(cfg2, null, 2), { mode: 384 });
|
|
43398
43700
|
}
|
|
43399
43701
|
function ccr(args, timeout = 8e3) {
|
|
43400
43702
|
const { exe, asNode } = nodeExe();
|
|
43401
|
-
return new Promise((
|
|
43703
|
+
return new Promise((resolve9) => {
|
|
43402
43704
|
execFile2(exe, [ccrCliPath(), ...args], { env: ccrEnv(asNode), timeout }, (err, stdout, stderr) => {
|
|
43403
|
-
|
|
43705
|
+
resolve9({ ok: !err, out: `${stdout || ""}${stderr || ""}` });
|
|
43404
43706
|
});
|
|
43405
43707
|
});
|
|
43406
43708
|
}
|
|
43407
43709
|
function waitHealthy(timeoutMs = 8e3) {
|
|
43408
43710
|
const deadline = Date.now() + timeoutMs;
|
|
43409
|
-
const ping = () => new Promise((
|
|
43711
|
+
const ping = () => new Promise((resolve9) => {
|
|
43410
43712
|
const req = httpRequest({ host: BIND_HOST, port: ROUTER_PORT, path: "/", method: "GET", timeout: 1e3 }, (res) => {
|
|
43411
43713
|
res.resume();
|
|
43412
|
-
|
|
43714
|
+
resolve9(true);
|
|
43413
43715
|
});
|
|
43414
|
-
req.on("error", () =>
|
|
43716
|
+
req.on("error", () => resolve9(false));
|
|
43415
43717
|
req.on("timeout", () => {
|
|
43416
43718
|
req.destroy();
|
|
43417
|
-
|
|
43719
|
+
resolve9(false);
|
|
43418
43720
|
});
|
|
43419
43721
|
req.end();
|
|
43420
43722
|
});
|
|
43421
|
-
return new Promise((
|
|
43723
|
+
return new Promise((resolve9) => {
|
|
43422
43724
|
const tick = async () => {
|
|
43423
43725
|
if (await ping())
|
|
43424
|
-
return
|
|
43726
|
+
return resolve9(true);
|
|
43425
43727
|
if (Date.now() > deadline)
|
|
43426
|
-
return
|
|
43728
|
+
return resolve9(false);
|
|
43427
43729
|
setTimeout(() => void tick(), 400);
|
|
43428
43730
|
};
|
|
43429
43731
|
void tick();
|
|
@@ -43463,13 +43765,13 @@ function routerEndpointSync(desired) {
|
|
|
43463
43765
|
}
|
|
43464
43766
|
|
|
43465
43767
|
// ../../packages/host-core/dist/runners/resolve.js
|
|
43466
|
-
var runnerHomeBase =
|
|
43768
|
+
var runnerHomeBase = join11(homedir5(), ".tesseract", "runner-home");
|
|
43467
43769
|
function materializeClaudeAuthHome(contents) {
|
|
43468
43770
|
const id = createHash2("sha256").update(contents).digest("hex").slice(0, 16);
|
|
43469
|
-
const home =
|
|
43771
|
+
const home = join11(runnerHomeBase, id);
|
|
43470
43772
|
try {
|
|
43471
43773
|
mkdirSync4(home, { recursive: true });
|
|
43472
|
-
writeFileSync5(
|
|
43774
|
+
writeFileSync5(join11(home, ".credentials.json"), contents, { mode: 384 });
|
|
43473
43775
|
} catch {
|
|
43474
43776
|
}
|
|
43475
43777
|
return home;
|
|
@@ -43519,7 +43821,7 @@ function resolveRunnerEnv(spec) {
|
|
|
43519
43821
|
return { ANTHROPIC_BASE_URL: endpoint.baseUrl, ANTHROPIC_AUTH_TOKEN: endpoint.authToken, ANTHROPIC_API_KEY: "" };
|
|
43520
43822
|
}
|
|
43521
43823
|
function overridePath() {
|
|
43522
|
-
return
|
|
43824
|
+
return join11(process.env.CCB_TESSERACT_DIR ?? join11(homedir5(), ".tesseract"), "runners.json");
|
|
43523
43825
|
}
|
|
43524
43826
|
var cache2 = null;
|
|
43525
43827
|
var cachedMtime = -1;
|
|
@@ -43533,7 +43835,7 @@ function readOverride() {
|
|
|
43533
43835
|
}
|
|
43534
43836
|
const m = statSync(p).mtimeMs;
|
|
43535
43837
|
if (cachedMtime !== m) {
|
|
43536
|
-
cache2 = JSON.parse(
|
|
43838
|
+
cache2 = JSON.parse(readFileSync5(p, "utf-8"));
|
|
43537
43839
|
cachedMtime = m;
|
|
43538
43840
|
}
|
|
43539
43841
|
} catch {
|
|
@@ -43560,11 +43862,11 @@ function resolveOverrideEngineEnv() {
|
|
|
43560
43862
|
}
|
|
43561
43863
|
|
|
43562
43864
|
// ../../packages/host-core/dist/runners/pool.js
|
|
43563
|
-
import { readFileSync as
|
|
43564
|
-
import { join as
|
|
43865
|
+
import { readFileSync as readFileSync6, writeFileSync as writeFileSync6, existsSync as existsSync7, statSync as statSync2, mkdirSync as mkdirSync5, chmodSync as chmodSync2, renameSync as renameSync4 } from "node:fs";
|
|
43866
|
+
import { join as join12 } from "node:path";
|
|
43565
43867
|
import { randomUUID as randomUUID5 } from "node:crypto";
|
|
43566
43868
|
function poolPath() {
|
|
43567
|
-
return
|
|
43869
|
+
return join12(daemonDir(), "runner-configs.json");
|
|
43568
43870
|
}
|
|
43569
43871
|
var cache3 = null;
|
|
43570
43872
|
var cachedMtime2 = -1;
|
|
@@ -43581,7 +43883,7 @@ function load() {
|
|
|
43581
43883
|
}
|
|
43582
43884
|
const m = statSync2(p).mtimeMs;
|
|
43583
43885
|
if (cachedMtime2 !== m || !cache3) {
|
|
43584
|
-
const parsed = JSON.parse(
|
|
43886
|
+
const parsed = JSON.parse(readFileSync6(p, "utf-8"));
|
|
43585
43887
|
cache3 = parsed && parsed.version === 1 && Array.isArray(parsed.configs) ? parsed : emptyStore();
|
|
43586
43888
|
cachedMtime2 = m;
|
|
43587
43889
|
}
|
|
@@ -43747,7 +44049,7 @@ function setActiveConfig(id) {
|
|
|
43747
44049
|
// ../../packages/host-core/dist/daemon-engine-spawn.js
|
|
43748
44050
|
import { execFileSync } from "node:child_process";
|
|
43749
44051
|
import { homedir as homedir6 } from "node:os";
|
|
43750
|
-
import { join as
|
|
44052
|
+
import { join as join13 } from "node:path";
|
|
43751
44053
|
function envKey(id) {
|
|
43752
44054
|
return id.toUpperCase().replace(/[^A-Z0-9]/g, "_");
|
|
43753
44055
|
}
|
|
@@ -43758,10 +44060,10 @@ function augmentedPath() {
|
|
|
43758
44060
|
"/opt/homebrew/bin",
|
|
43759
44061
|
"/usr/bin",
|
|
43760
44062
|
"/bin",
|
|
43761
|
-
|
|
43762
|
-
|
|
43763
|
-
|
|
43764
|
-
|
|
44063
|
+
join13(homedir6(), ".local", "bin"),
|
|
44064
|
+
join13(homedir6(), "bin"),
|
|
44065
|
+
join13(homedir6(), ".bun", "bin"),
|
|
44066
|
+
join13(homedir6(), ".npm-global", "bin")
|
|
43765
44067
|
];
|
|
43766
44068
|
const seen = /* @__PURE__ */ new Set();
|
|
43767
44069
|
const parts = [];
|
|
@@ -43774,9 +44076,9 @@ function augmentedPath() {
|
|
|
43774
44076
|
return parts.join(sep7);
|
|
43775
44077
|
}
|
|
43776
44078
|
function which(bin, path5) {
|
|
43777
|
-
const
|
|
44079
|
+
const tool3 = process.platform === "win32" ? "where" : "which";
|
|
43778
44080
|
try {
|
|
43779
|
-
const out = execFileSync(
|
|
44081
|
+
const out = execFileSync(tool3, [bin], { env: { ...process.env, PATH: path5 }, timeout: 4e3, encoding: "utf-8" });
|
|
43780
44082
|
return out.split(/\r?\n/).map((l) => l.trim()).find(Boolean) || void 0;
|
|
43781
44083
|
} catch {
|
|
43782
44084
|
return void 0;
|
|
@@ -43818,14 +44120,14 @@ function readDaemonEngineSpawn(engineId) {
|
|
|
43818
44120
|
return readDaemonAgentSettings().engineSpawn?.[engineId] ?? resolveDaemonEngineSpawn(engineId);
|
|
43819
44121
|
}
|
|
43820
44122
|
function agentSettingsPath() {
|
|
43821
|
-
return
|
|
44123
|
+
return join14(daemonDir(), "agent-settings.json");
|
|
43822
44124
|
}
|
|
43823
44125
|
function readDaemonSchedulingEnabled() {
|
|
43824
44126
|
return readDaemonAgentSettings().schedulingEnabled === true;
|
|
43825
44127
|
}
|
|
43826
44128
|
function readDaemonAgentSettings() {
|
|
43827
44129
|
try {
|
|
43828
|
-
return JSON.parse(
|
|
44130
|
+
return JSON.parse(readFileSync7(agentSettingsPath(), "utf-8"));
|
|
43829
44131
|
} catch {
|
|
43830
44132
|
const snap = {};
|
|
43831
44133
|
const raw = process.env.CCB_MCP_SERVERS;
|
|
@@ -43932,7 +44234,7 @@ function buildSharedBackend(engineId) {
|
|
|
43932
44234
|
},
|
|
43933
44235
|
resolver,
|
|
43934
44236
|
// Daemon plugins (review #3): operator-controlled <daemonDir>/plugins, env-var secrets.
|
|
43935
|
-
buildDaemonPluginLoader(
|
|
44237
|
+
buildDaemonPluginLoader(join15(daemonDir(), "plugins"))
|
|
43936
44238
|
).then((b) => {
|
|
43937
44239
|
if (token !== buildToken)
|
|
43938
44240
|
return b;
|
|
@@ -43983,16 +44285,16 @@ function refreshDaemonScheduling(b) {
|
|
|
43983
44285
|
}
|
|
43984
44286
|
b.configureScheduling({
|
|
43985
44287
|
enabled,
|
|
43986
|
-
file:
|
|
44288
|
+
file: join15(dir, "scheduled_tasks.json"),
|
|
43987
44289
|
// projectDir omitted ⇒ fires track the daemon's currently-open project (setConfig).
|
|
43988
44290
|
isOwner: schedulingLock ? () => schedulingLock.isOwner() : void 0
|
|
43989
44291
|
});
|
|
43990
44292
|
}
|
|
43991
44293
|
|
|
43992
44294
|
// ../../packages/host-core/dist/fs-remote.js
|
|
43993
|
-
import { readdir as readdir2, readFile as
|
|
44295
|
+
import { readdir as readdir2, readFile as readFile6, writeFile as writeFile4, mkdir as mkdir4, cp, rm, rename as renameAsync, stat as stat2 } from "node:fs/promises";
|
|
43994
44296
|
import { openSync as openSync2, readSync, closeSync as closeSync2, statSync as statSync3, existsSync as existsSync8, watch } from "node:fs";
|
|
43995
|
-
import { basename as basename2, dirname as dirname6, join as
|
|
44297
|
+
import { basename as basename2, dirname as dirname6, join as join16, relative as relative3, resolve as resolve4, sep as sep3, isAbsolute as isAbsolute3 } from "node:path";
|
|
43996
44298
|
import { execFile as execFile3 } from "node:child_process";
|
|
43997
44299
|
import { promisify as promisify2 } from "node:util";
|
|
43998
44300
|
var execFileAsync = promisify2(execFile3);
|
|
@@ -44039,12 +44341,12 @@ async function listAllFilesUnder(dir) {
|
|
|
44039
44341
|
return;
|
|
44040
44342
|
if (ent.name === ".DS_Store")
|
|
44041
44343
|
continue;
|
|
44042
|
-
const full =
|
|
44344
|
+
const full = join16(d, ent.name);
|
|
44043
44345
|
if (ent.isDirectory()) {
|
|
44044
44346
|
if (!LISTALL_SKIP_DIRS.has(ent.name))
|
|
44045
44347
|
await walk(full);
|
|
44046
44348
|
} else if (ent.isFile())
|
|
44047
|
-
out.push(
|
|
44349
|
+
out.push(relative3(dir, full).split(sep3).join("/"));
|
|
44048
44350
|
}
|
|
44049
44351
|
};
|
|
44050
44352
|
await walk(dir);
|
|
@@ -44155,18 +44457,18 @@ function resolveParent(raw, root) {
|
|
|
44155
44457
|
if (raw === "" || raw === "~")
|
|
44156
44458
|
return root;
|
|
44157
44459
|
if (raw.startsWith("~/"))
|
|
44158
|
-
return
|
|
44159
|
-
return
|
|
44460
|
+
return join16(root, raw.slice(2));
|
|
44461
|
+
return isAbsolute3(raw) ? raw : join16(root, raw);
|
|
44160
44462
|
}
|
|
44161
44463
|
function resolveUniqueName(dir, name) {
|
|
44162
|
-
const direct =
|
|
44464
|
+
const direct = join16(dir, name);
|
|
44163
44465
|
if (!existsSync8(direct))
|
|
44164
44466
|
return direct;
|
|
44165
44467
|
const dot = name.lastIndexOf(".");
|
|
44166
44468
|
const base = dot > 0 ? name.slice(0, dot) : name;
|
|
44167
44469
|
const ext = dot > 0 ? name.slice(dot) : "";
|
|
44168
44470
|
for (let i = 2; i < 1e4; i++) {
|
|
44169
|
-
const candidate =
|
|
44471
|
+
const candidate = join16(dir, `${base} ${i}${ext}`);
|
|
44170
44472
|
if (!existsSync8(candidate))
|
|
44171
44473
|
return candidate;
|
|
44172
44474
|
}
|
|
@@ -44183,7 +44485,7 @@ async function readRemoteBytes(root, path5) {
|
|
|
44183
44485
|
return { error: "Not a file" };
|
|
44184
44486
|
if (s.size > REMOTE_READ_CAP)
|
|
44185
44487
|
return { error: `File is too large to read whole over the network (${(s.size / 1024 / 1024).toFixed(1)} MB) \u2014 open it locally.` };
|
|
44186
|
-
return { bytes: await
|
|
44488
|
+
return { bytes: await readFile6(path5), size: s.size };
|
|
44187
44489
|
} catch (err) {
|
|
44188
44490
|
return { error: String(err.message) };
|
|
44189
44491
|
}
|
|
@@ -44198,7 +44500,7 @@ async function runRemoteFsOp(root, op, args) {
|
|
|
44198
44500
|
try {
|
|
44199
44501
|
const entries = (await readdir2(dir, { withFileTypes: true })).filter((e) => e.name !== ".DS_Store");
|
|
44200
44502
|
const ignored = await gitIgnoredNames(dir, entries.map((e) => e.name));
|
|
44201
|
-
return entries.map((e) => ({ name: e.name, path:
|
|
44503
|
+
return entries.map((e) => ({ name: e.name, path: join16(dir, e.name), isDir: e.isDirectory(), ignored: ignored.has(e.name) })).sort((x, y) => x.isDir === y.isDir ? x.name.localeCompare(y.name) : x.isDir ? -1 : 1);
|
|
44202
44504
|
} catch {
|
|
44203
44505
|
return [];
|
|
44204
44506
|
}
|
|
@@ -44224,7 +44526,7 @@ async function runRemoteFsOp(root, op, args) {
|
|
|
44224
44526
|
const s = statSync3(p);
|
|
44225
44527
|
if (s.size > TEXT_SIZE_LIMIT)
|
|
44226
44528
|
return { error: "File too large for text view." };
|
|
44227
|
-
return { content: await
|
|
44529
|
+
return { content: await readFile6(p, "utf-8") };
|
|
44228
44530
|
} catch (err) {
|
|
44229
44531
|
return { error: String(err.message) };
|
|
44230
44532
|
}
|
|
@@ -44235,8 +44537,8 @@ async function runRemoteFsOp(root, op, args) {
|
|
|
44235
44537
|
if (!isInsideRoot(p, root))
|
|
44236
44538
|
return OUTSIDE("write");
|
|
44237
44539
|
try {
|
|
44238
|
-
await
|
|
44239
|
-
await
|
|
44540
|
+
await mkdir4(dirname6(p), { recursive: true });
|
|
44541
|
+
await writeFile4(p, content, "utf-8");
|
|
44240
44542
|
return { ok: true };
|
|
44241
44543
|
} catch (err) {
|
|
44242
44544
|
return { ok: false, error: String(err.message) };
|
|
@@ -44248,8 +44550,8 @@ async function runRemoteFsOp(root, op, args) {
|
|
|
44248
44550
|
if (!isInsideRoot(p, root))
|
|
44249
44551
|
return OUTSIDE("write");
|
|
44250
44552
|
try {
|
|
44251
|
-
await
|
|
44252
|
-
await
|
|
44553
|
+
await mkdir4(dirname6(p), { recursive: true });
|
|
44554
|
+
await writeFile4(p, Buffer.from(base643, "base64"));
|
|
44253
44555
|
return { ok: true };
|
|
44254
44556
|
} catch (err) {
|
|
44255
44557
|
return { ok: false, error: String(err.message) };
|
|
@@ -44301,7 +44603,7 @@ async function runRemoteFsOp(root, op, args) {
|
|
|
44301
44603
|
const s = statSync3(p);
|
|
44302
44604
|
if (s.size > REMOTE_READ_CAP)
|
|
44303
44605
|
return { error: `File is too large to read whole over the network (${(s.size / 1024 / 1024).toFixed(1)} MB) \u2014 open it locally.` };
|
|
44304
|
-
return { base64: (await
|
|
44606
|
+
return { base64: (await readFile6(p)).toString("base64"), size: s.size };
|
|
44305
44607
|
} catch (err) {
|
|
44306
44608
|
return { error: String(err.message) };
|
|
44307
44609
|
}
|
|
@@ -44311,13 +44613,13 @@ async function runRemoteFsOp(root, op, args) {
|
|
|
44311
44613
|
const name = String(a[1] ?? "").trim();
|
|
44312
44614
|
if (!validName(name))
|
|
44313
44615
|
return { ok: false, error: "Invalid project name." };
|
|
44314
|
-
const target =
|
|
44616
|
+
const target = join16(parent, name);
|
|
44315
44617
|
if (!isInsideRoot(target, root))
|
|
44316
44618
|
return { ok: false, error: "Refusing to create a project outside the shared root." };
|
|
44317
44619
|
if (existsSync8(target))
|
|
44318
44620
|
return { ok: false, error: `A folder named "${name}" already exists.` };
|
|
44319
44621
|
try {
|
|
44320
|
-
await
|
|
44622
|
+
await mkdir4(target, { recursive: true });
|
|
44321
44623
|
return { ok: true, path: target };
|
|
44322
44624
|
} catch (err) {
|
|
44323
44625
|
return { ok: false, error: String(err.message) };
|
|
@@ -44331,14 +44633,14 @@ async function runRemoteFsOp(root, op, args) {
|
|
|
44331
44633
|
return { ok: false, error: "Invalid name." };
|
|
44332
44634
|
if (!isInsideRoot(parent, root))
|
|
44333
44635
|
return OUTSIDE("create");
|
|
44334
|
-
const target =
|
|
44636
|
+
const target = join16(parent, name);
|
|
44335
44637
|
if (existsSync8(target))
|
|
44336
44638
|
return { ok: false, error: `"${name}" already exists.` };
|
|
44337
44639
|
try {
|
|
44338
44640
|
if (op === "createFile")
|
|
44339
|
-
await
|
|
44641
|
+
await writeFile4(target, "", "utf-8");
|
|
44340
44642
|
else
|
|
44341
|
-
await
|
|
44643
|
+
await mkdir4(target);
|
|
44342
44644
|
return { ok: true, path: target };
|
|
44343
44645
|
} catch (err) {
|
|
44344
44646
|
return { ok: false, error: String(err.message) };
|
|
@@ -44351,7 +44653,7 @@ async function runRemoteFsOp(root, op, args) {
|
|
|
44351
44653
|
return { ok: false, error: "Invalid name." };
|
|
44352
44654
|
if (!isInsideRoot(oldPath, root))
|
|
44353
44655
|
return OUTSIDE("rename");
|
|
44354
|
-
const newPath =
|
|
44656
|
+
const newPath = join16(dirname6(oldPath), newName);
|
|
44355
44657
|
if (existsSync8(newPath))
|
|
44356
44658
|
return { ok: false, error: `A file named "${newName}" already exists.` };
|
|
44357
44659
|
try {
|
|
@@ -44367,7 +44669,7 @@ async function runRemoteFsOp(root, op, args) {
|
|
|
44367
44669
|
return { ok: false, error: "Bad request" };
|
|
44368
44670
|
if (!isInsideRoot(p, root))
|
|
44369
44671
|
return OUTSIDE("delete");
|
|
44370
|
-
if (
|
|
44672
|
+
if (resolve4(p) === resolve4(root))
|
|
44371
44673
|
return { ok: false, error: "Refusing to delete the shared root." };
|
|
44372
44674
|
try {
|
|
44373
44675
|
await rm(p, { recursive: true, force: false });
|
|
@@ -44413,7 +44715,7 @@ async function runRemoteFsOp(root, op, args) {
|
|
|
44413
44715
|
const s = await stat2(p);
|
|
44414
44716
|
if (!s.isDirectory())
|
|
44415
44717
|
return { error: "not_dir" };
|
|
44416
|
-
return { root:
|
|
44718
|
+
return { root: resolve4(p), name: basename2(p) };
|
|
44417
44719
|
} catch {
|
|
44418
44720
|
return { error: "not_found" };
|
|
44419
44721
|
}
|
|
@@ -44421,14 +44723,14 @@ async function runRemoteFsOp(root, op, args) {
|
|
|
44421
44723
|
case "currentRoot":
|
|
44422
44724
|
return { root, name: basename2(root) };
|
|
44423
44725
|
case "homeDir":
|
|
44424
|
-
return { root:
|
|
44726
|
+
return { root: resolve4(root), name: basename2(root) };
|
|
44425
44727
|
default:
|
|
44426
44728
|
return { error: `Unsupported fs op: ${op}` };
|
|
44427
44729
|
}
|
|
44428
44730
|
}
|
|
44429
44731
|
var remoteWatches = /* @__PURE__ */ new Map();
|
|
44430
44732
|
function watchRemoteRoot(root, key2, onChange) {
|
|
44431
|
-
const resolved =
|
|
44733
|
+
const resolved = resolve4(root);
|
|
44432
44734
|
const existing = remoteWatches.get(resolved);
|
|
44433
44735
|
if (existing) {
|
|
44434
44736
|
existing.listeners.set(key2, onChange);
|
|
@@ -44443,7 +44745,7 @@ function watchRemoteRoot(root, key2, onChange) {
|
|
|
44443
44745
|
const rel = String(filename);
|
|
44444
44746
|
if (rel.split(sep3).some((seg) => IGNORED.has(seg)))
|
|
44445
44747
|
return;
|
|
44446
|
-
pending.add(
|
|
44748
|
+
pending.add(join16(resolved, rel));
|
|
44447
44749
|
if (timer)
|
|
44448
44750
|
clearTimeout(timer);
|
|
44449
44751
|
timer = setTimeout(() => {
|
|
@@ -44688,15 +44990,15 @@ function dynamicMetrics() {
|
|
|
44688
44990
|
}
|
|
44689
44991
|
|
|
44690
44992
|
// ../../packages/host-core/dist/fs-transfer.js
|
|
44691
|
-
import { readdir as readdir3, lstat, mkdir as
|
|
44993
|
+
import { readdir as readdir3, lstat, mkdir as mkdir5, chmod, rm as rm2, readlink, symlink, stat as stat3 } from "node:fs/promises";
|
|
44692
44994
|
import { openSync as openSync3, readSync as readSync2, closeSync as closeSync3, existsSync as existsSync9, createWriteStream } from "node:fs";
|
|
44693
|
-
import { dirname as dirname7, join as
|
|
44995
|
+
import { dirname as dirname7, join as join18, relative as relative5, sep as sep5 } from "node:path";
|
|
44694
44996
|
|
|
44695
44997
|
// ../../packages/host-core/dist/active-link/paths.js
|
|
44696
44998
|
import { homedir as homedir7 } from "node:os";
|
|
44697
|
-
import { join as
|
|
44999
|
+
import { join as join17, relative as relative4, sep as sep4 } from "node:path";
|
|
44698
45000
|
function activeLinkEnabled() {
|
|
44699
|
-
return process.env.CCB_ACTIVE_LINK
|
|
45001
|
+
return process.env.CCB_ACTIVE_LINK !== "0";
|
|
44700
45002
|
}
|
|
44701
45003
|
var HEAVY_DIRS = /* @__PURE__ */ new Set([
|
|
44702
45004
|
".git",
|
|
@@ -44717,10 +45019,10 @@ function isExcludedName(name) {
|
|
|
44717
45019
|
return HEAVY_DIRS.has(name) || ALWAYS_SKIP.has(name);
|
|
44718
45020
|
}
|
|
44719
45021
|
function toPosixRel(root, abs) {
|
|
44720
|
-
return
|
|
45022
|
+
return relative4(root, abs).split(sep4).join("/");
|
|
44721
45023
|
}
|
|
44722
45024
|
function fromPosixRel(root, rel) {
|
|
44723
|
-
return
|
|
45025
|
+
return join17(root, rel.split("/").join(sep4));
|
|
44724
45026
|
}
|
|
44725
45027
|
function isExcludedAbs(abs, root) {
|
|
44726
45028
|
const rel = toPosixRel(root, abs);
|
|
@@ -44729,10 +45031,10 @@ function isExcludedAbs(abs, root) {
|
|
|
44729
45031
|
return rel.split("/").some(isExcludedName);
|
|
44730
45032
|
}
|
|
44731
45033
|
function activeLinkRoot() {
|
|
44732
|
-
return process.env.CCB_ACTIVE_LINK_DIR ??
|
|
45034
|
+
return process.env.CCB_ACTIVE_LINK_DIR ?? join17(homedir7(), ".tesseract", "active-link");
|
|
44733
45035
|
}
|
|
44734
45036
|
function linkStateDir(linkId) {
|
|
44735
|
-
return
|
|
45037
|
+
return join17(activeLinkRoot(), linkId);
|
|
44736
45038
|
}
|
|
44737
45039
|
|
|
44738
45040
|
// ../../packages/host-core/dist/fs-transfer.js
|
|
@@ -44745,9 +45047,9 @@ function clearTimer(t) {
|
|
|
44745
45047
|
return null;
|
|
44746
45048
|
}
|
|
44747
45049
|
function uniqueDir(parent, name) {
|
|
44748
|
-
let candidate =
|
|
45050
|
+
let candidate = join18(parent, name);
|
|
44749
45051
|
for (let i = 2; existsSync9(candidate) && i < 1e4; i++)
|
|
44750
|
-
candidate =
|
|
45052
|
+
candidate = join18(parent, `${name} ${i}`);
|
|
44751
45053
|
return candidate;
|
|
44752
45054
|
}
|
|
44753
45055
|
var producers = /* @__PURE__ */ new Map();
|
|
@@ -44790,8 +45092,8 @@ async function buildManifest(root, followSymlinks, excludeHeavy) {
|
|
|
44790
45092
|
continue;
|
|
44791
45093
|
if (e.isDirectory() && excludeHeavy && HEAVY_DIRS.has(e.name))
|
|
44792
45094
|
continue;
|
|
44793
|
-
const abs =
|
|
44794
|
-
const rel =
|
|
45095
|
+
const abs = join18(dir, e.name);
|
|
45096
|
+
const rel = relative5(root, abs).split(sep5).join("/");
|
|
44795
45097
|
const st = await lstat(abs).catch(() => null);
|
|
44796
45098
|
if (!st)
|
|
44797
45099
|
continue;
|
|
@@ -44851,17 +45153,17 @@ async function startOutboundTransfer(msg, controllerClientId, ownHostId2, hostRo
|
|
|
44851
45153
|
totalBytes: manifest.totalBytes,
|
|
44852
45154
|
dirs: manifest.dirs
|
|
44853
45155
|
}, { hostId: toHost });
|
|
44854
|
-
const waitWindow = () => state.sentBytes - state.ackedBytes < MAX_INFLIGHT ? Promise.resolve() : new Promise((
|
|
44855
|
-
state.wake =
|
|
45156
|
+
const waitWindow = () => state.sentBytes - state.ackedBytes < MAX_INFLIGHT ? Promise.resolve() : new Promise((resolve9) => {
|
|
45157
|
+
state.wake = resolve9;
|
|
44856
45158
|
});
|
|
44857
45159
|
for (let fileIx = 0; fileIx < manifest.files.length && !state.cancelled; fileIx++) {
|
|
44858
45160
|
const f = manifest.files[fileIx];
|
|
44859
45161
|
if (f.kind === "symlink") {
|
|
44860
|
-
const target = await readlink(
|
|
45162
|
+
const target = await readlink(join18(srcPath, f.rel.split("/").join(sep5))).catch(() => "");
|
|
44861
45163
|
send2({ type: "fs:transferChunk", transferId, toHost, fileIx, rel: f.rel, mode: f.mode, kind: "symlink", offset: 0, base64: Buffer.from(target, "utf-8").toString("base64"), eof: true }, { hostId: toHost });
|
|
44862
45164
|
continue;
|
|
44863
45165
|
}
|
|
44864
|
-
const abs =
|
|
45166
|
+
const abs = join18(srcPath, f.rel.split("/").join(sep5));
|
|
44865
45167
|
let fd = null;
|
|
44866
45168
|
try {
|
|
44867
45169
|
fd = openSync3(abs, "r");
|
|
@@ -44973,7 +45275,7 @@ async function beginInboundTransfer(msg, hostRoot, send2) {
|
|
|
44973
45275
|
failNoState("Invalid destination name.");
|
|
44974
45276
|
return;
|
|
44975
45277
|
}
|
|
44976
|
-
let destRoot =
|
|
45278
|
+
let destRoot = join18(parent, msg.destName);
|
|
44977
45279
|
let createdRoot = false;
|
|
44978
45280
|
if (existsSync9(destRoot)) {
|
|
44979
45281
|
if (msg.onCollision === "abort") {
|
|
@@ -45013,11 +45315,11 @@ async function beginInboundTransfer(msg, hostRoot, send2) {
|
|
|
45013
45315
|
return;
|
|
45014
45316
|
}
|
|
45015
45317
|
try {
|
|
45016
|
-
await
|
|
45318
|
+
await mkdir5(destRoot, { recursive: true });
|
|
45017
45319
|
for (const d of msg.dirs) {
|
|
45018
|
-
const abs =
|
|
45320
|
+
const abs = join18(destRoot, d.rel.split("/").join(sep5));
|
|
45019
45321
|
if (isInsideRoot(abs, destRoot))
|
|
45020
|
-
await
|
|
45322
|
+
await mkdir5(abs, { recursive: true }).catch(() => {
|
|
45021
45323
|
});
|
|
45022
45324
|
}
|
|
45023
45325
|
} catch (e) {
|
|
@@ -45029,7 +45331,7 @@ async function writeInboundChunk(msg, send2) {
|
|
|
45029
45331
|
if (!s || s.cancelled)
|
|
45030
45332
|
return;
|
|
45031
45333
|
armConsumerWatchdog(msg.transferId, send2);
|
|
45032
|
-
const abs =
|
|
45334
|
+
const abs = join18(s.destRoot, msg.rel.split("/").join(sep5));
|
|
45033
45335
|
if (msg.rel.includes("..") || !isInsideRoot(abs, s.destRoot)) {
|
|
45034
45336
|
failConsumer(msg.transferId, `Refusing a path outside the destination: ${msg.rel}`, send2);
|
|
45035
45337
|
return;
|
|
@@ -45037,9 +45339,9 @@ async function writeInboundChunk(msg, send2) {
|
|
|
45037
45339
|
try {
|
|
45038
45340
|
if (msg.kind === "symlink") {
|
|
45039
45341
|
const target = Buffer.from(msg.base64, "base64").toString("utf-8");
|
|
45040
|
-
const resolved =
|
|
45342
|
+
const resolved = join18(dirname7(abs), target);
|
|
45041
45343
|
if (isInsideRoot(resolved, s.destRoot)) {
|
|
45042
|
-
await
|
|
45344
|
+
await mkdir5(dirname7(abs), { recursive: true }).catch(() => {
|
|
45043
45345
|
});
|
|
45044
45346
|
await symlink(target, abs).catch(() => {
|
|
45045
45347
|
});
|
|
@@ -45052,14 +45354,14 @@ async function writeInboundChunk(msg, send2) {
|
|
|
45052
45354
|
if (s.curIx !== msg.fileIx || !s.curStream) {
|
|
45053
45355
|
if (s.curStream)
|
|
45054
45356
|
await new Promise((r) => s.curStream.end(r));
|
|
45055
|
-
await
|
|
45357
|
+
await mkdir5(dirname7(abs), { recursive: true }).catch(() => {
|
|
45056
45358
|
});
|
|
45057
45359
|
s.curStream = createWriteStream(abs);
|
|
45058
45360
|
s.curIx = msg.fileIx;
|
|
45059
45361
|
}
|
|
45060
45362
|
if (msg.base64) {
|
|
45061
45363
|
const buf = Buffer.from(msg.base64, "base64");
|
|
45062
|
-
await new Promise((
|
|
45364
|
+
await new Promise((resolve9, reject) => s.curStream.write(buf, (err) => err ? reject(err) : resolve9()));
|
|
45063
45365
|
s.bytesDone += buf.length;
|
|
45064
45366
|
}
|
|
45065
45367
|
if (msg.eof) {
|
|
@@ -45113,7 +45415,7 @@ function cancelTransfersForClient(clientId, send2) {
|
|
|
45113
45415
|
|
|
45114
45416
|
// ../../packages/host-core/dist/peer-link/index.js
|
|
45115
45417
|
import { homedir as homedir8 } from "node:os";
|
|
45116
|
-
import { join as
|
|
45418
|
+
import { join as join19 } from "node:path";
|
|
45117
45419
|
|
|
45118
45420
|
// ../../packages/host-core/dist/peer-link/manager.js
|
|
45119
45421
|
import { randomBytes as randomBytes2 } from "node:crypto";
|
|
@@ -45122,15 +45424,15 @@ import { randomBytes as randomBytes2 } from "node:crypto";
|
|
|
45122
45424
|
var import_selfsigned = __toESM(require_selfsigned(), 1);
|
|
45123
45425
|
import tls from "node:tls";
|
|
45124
45426
|
import { X509Certificate } from "node:crypto";
|
|
45125
|
-
import { readFileSync as
|
|
45427
|
+
import { readFileSync as readFileSync8, writeFileSync as writeFileSync7, existsSync as existsSync10, mkdirSync as mkdirSync6 } from "node:fs";
|
|
45126
45428
|
import { dirname as dirname8 } from "node:path";
|
|
45127
45429
|
function fingerprintOf(certPem) {
|
|
45128
45430
|
return new X509Certificate(certPem).fingerprint256;
|
|
45129
45431
|
}
|
|
45130
45432
|
async function loadOrCreateIdentity(certPath, keyPath) {
|
|
45131
45433
|
if (existsSync10(certPath) && existsSync10(keyPath)) {
|
|
45132
|
-
const cert =
|
|
45133
|
-
const key2 =
|
|
45434
|
+
const cert = readFileSync8(certPath, "utf8");
|
|
45435
|
+
const key2 = readFileSync8(keyPath, "utf8");
|
|
45134
45436
|
return { cert, key: key2, fingerprint256: fingerprintOf(cert) };
|
|
45135
45437
|
}
|
|
45136
45438
|
const tenYears = new Date(Date.now() + 10 * 365 * 24 * 60 * 60 * 1e3);
|
|
@@ -45147,7 +45449,7 @@ async function loadOrCreateIdentity(certPath, keyPath) {
|
|
|
45147
45449
|
return { cert: pems.cert, key: pems.private, fingerprint256: fingerprintOf(pems.cert) };
|
|
45148
45450
|
}
|
|
45149
45451
|
function pinnedConnect(opts) {
|
|
45150
|
-
return new Promise((
|
|
45452
|
+
return new Promise((resolve9, reject) => {
|
|
45151
45453
|
let settled = false;
|
|
45152
45454
|
const done = (err, sock) => {
|
|
45153
45455
|
if (settled)
|
|
@@ -45160,7 +45462,7 @@ function pinnedConnect(opts) {
|
|
|
45160
45462
|
}
|
|
45161
45463
|
reject(err);
|
|
45162
45464
|
} else
|
|
45163
|
-
|
|
45465
|
+
resolve9(sock);
|
|
45164
45466
|
};
|
|
45165
45467
|
const socket2 = tls.connect({
|
|
45166
45468
|
host: opts.host,
|
|
@@ -45367,7 +45669,7 @@ var PeerLinkManager = class {
|
|
|
45367
45669
|
if (this.server)
|
|
45368
45670
|
return this.listenPort;
|
|
45369
45671
|
this.server = createListener(identity, LISTEN_PORT, (sock) => this.acceptInbound(sock, "reverse"));
|
|
45370
|
-
await new Promise((
|
|
45672
|
+
await new Promise((resolve9) => this.server.once("listening", () => resolve9()));
|
|
45371
45673
|
const addr = this.server.address();
|
|
45372
45674
|
if (addr && typeof addr === "object")
|
|
45373
45675
|
this.listenPort = addr.port;
|
|
@@ -45434,12 +45736,12 @@ var PeerLinkManager = class {
|
|
|
45434
45736
|
* peer to dial in. Resolves with the authed link, or rejects on timeout. */
|
|
45435
45737
|
awaitInbound(token, peerHostId) {
|
|
45436
45738
|
const h = toHex(token);
|
|
45437
|
-
return new Promise((
|
|
45739
|
+
return new Promise((resolve9, reject) => {
|
|
45438
45740
|
const timer = setTimeout(() => {
|
|
45439
45741
|
this.pendingInbound.delete(h);
|
|
45440
45742
|
reject(new Error("peer-link: inbound dial-in timeout"));
|
|
45441
45743
|
}, INBOUND_WAIT_MS);
|
|
45442
|
-
this.pendingInbound.set(h, { peerHostId, resolve:
|
|
45744
|
+
this.pendingInbound.set(h, { peerHostId, resolve: resolve9, reject, timer });
|
|
45443
45745
|
});
|
|
45444
45746
|
}
|
|
45445
45747
|
/** Obey one `p2p:go` (initiator OR unsolicited responder): dial the peer's
|
|
@@ -45466,7 +45768,7 @@ var PeerLinkManager = class {
|
|
|
45466
45768
|
];
|
|
45467
45769
|
if (quicOn)
|
|
45468
45770
|
attempts.push(this.quicDial(msg, token, udp[0]));
|
|
45469
|
-
return new Promise((
|
|
45771
|
+
return new Promise((resolve9, reject) => {
|
|
45470
45772
|
let done = false, failed = 0;
|
|
45471
45773
|
const errs = [];
|
|
45472
45774
|
for (const p of attempts) {
|
|
@@ -45480,7 +45782,7 @@ var PeerLinkManager = class {
|
|
|
45480
45782
|
}
|
|
45481
45783
|
done = true;
|
|
45482
45784
|
this.cache(msg.peerHostId, l);
|
|
45483
|
-
|
|
45785
|
+
resolve9(l);
|
|
45484
45786
|
}, (e) => {
|
|
45485
45787
|
errs.push(e);
|
|
45486
45788
|
if (++failed === attempts.length && !done)
|
|
@@ -45531,7 +45833,7 @@ var PeerLinkManager = class {
|
|
|
45531
45833
|
const myFingerprint = (await this.identity()).fingerprint256;
|
|
45532
45834
|
const rid = randomBytes2(8).toString("hex");
|
|
45533
45835
|
const myCandidates = gatherTcpCandidates(this.listenPort, this.observedIp);
|
|
45534
|
-
return new Promise((
|
|
45836
|
+
return new Promise((resolve9, reject) => {
|
|
45535
45837
|
let settled = false;
|
|
45536
45838
|
const overall = setTimeout(() => finish(new Error("peer-link: rendezvous timeout")), RENDEZVOUS_TIMEOUT_MS);
|
|
45537
45839
|
const finish = (err, link) => {
|
|
@@ -45543,7 +45845,7 @@ var PeerLinkManager = class {
|
|
|
45543
45845
|
if (err || !link)
|
|
45544
45846
|
reject(err ?? new Error("peer-link: no link"));
|
|
45545
45847
|
else
|
|
45546
|
-
|
|
45848
|
+
resolve9(link);
|
|
45547
45849
|
};
|
|
45548
45850
|
this.pendingOpens.set(rid, {
|
|
45549
45851
|
// Our attempt failed: tell the broker (it forwards `failed` to the peer +
|
|
@@ -45613,8 +45915,8 @@ var PeerLinkManager = class {
|
|
|
45613
45915
|
// ../../packages/host-core/dist/peer-link/index.js
|
|
45614
45916
|
var P2P_ENABLED = process.env.CCB_P2P !== "0";
|
|
45615
45917
|
function identityPaths() {
|
|
45616
|
-
const dir = process.env.CCB_P2P_DIR ??
|
|
45617
|
-
return { certPath:
|
|
45918
|
+
const dir = process.env.CCB_P2P_DIR ?? join19(homedir8(), ".tesseract");
|
|
45919
|
+
return { certPath: join19(dir, "peer-cert.pem"), keyPath: join19(dir, "peer-key.pem") };
|
|
45618
45920
|
}
|
|
45619
45921
|
var manager = null;
|
|
45620
45922
|
function peerLinkManager() {
|
|
@@ -45629,14 +45931,14 @@ async function openPeerLink(peerHostId, ctx) {
|
|
|
45629
45931
|
}
|
|
45630
45932
|
|
|
45631
45933
|
// ../../packages/host-core/dist/active-link/engine.js
|
|
45632
|
-
import { lstat as lstat6, readlink as readlink4, rm as rm3, mkdir as
|
|
45934
|
+
import { lstat as lstat6, readlink as readlink4, rm as rm3, mkdir as mkdir7, symlink as symlink2, rename as rename2, utimes as utimes2, writeFile as writeFile5 } from "node:fs/promises";
|
|
45633
45935
|
import { existsSync as existsSync12 } from "node:fs";
|
|
45634
|
-
import { dirname as dirname12, join as
|
|
45936
|
+
import { dirname as dirname12, join as join24, resolve as resolve7 } from "node:path";
|
|
45635
45937
|
|
|
45636
45938
|
// ../../packages/host-core/dist/active-link/blocks.js
|
|
45637
45939
|
import { createHash as createHash3 } from "node:crypto";
|
|
45638
45940
|
import { createReadStream } from "node:fs";
|
|
45639
|
-
import { open, mkdir as
|
|
45941
|
+
import { open, mkdir as mkdir6, rename, chmod as chmod2, utimes, unlink } from "node:fs/promises";
|
|
45640
45942
|
import { dirname as dirname9 } from "node:path";
|
|
45641
45943
|
var CHUNK3 = 1024 * 1024;
|
|
45642
45944
|
var MAX_INFLIGHT2 = 8 * CHUNK3;
|
|
@@ -45648,16 +45950,16 @@ function hashString(s) {
|
|
|
45648
45950
|
return createHash3("sha256").update(s, "utf-8").digest("hex");
|
|
45649
45951
|
}
|
|
45650
45952
|
function hashFile(abs) {
|
|
45651
|
-
return new Promise((
|
|
45953
|
+
return new Promise((resolve9, reject) => {
|
|
45652
45954
|
const h = createHash3("sha256");
|
|
45653
45955
|
const rs = createReadStream(abs);
|
|
45654
45956
|
rs.on("data", (d) => h.update(d));
|
|
45655
|
-
rs.on("end", () =>
|
|
45957
|
+
rs.on("end", () => resolve9(h.digest("hex")));
|
|
45656
45958
|
rs.on("error", reject);
|
|
45657
45959
|
});
|
|
45658
45960
|
}
|
|
45659
45961
|
function hashFileBlocks(abs) {
|
|
45660
|
-
return new Promise((
|
|
45962
|
+
return new Promise((resolve9, reject) => {
|
|
45661
45963
|
const whole = createHash3("sha256");
|
|
45662
45964
|
const blocks = [];
|
|
45663
45965
|
let cur = createHash3("sha256");
|
|
@@ -45684,7 +45986,7 @@ function hashFileBlocks(abs) {
|
|
|
45684
45986
|
rs.on("end", () => {
|
|
45685
45987
|
if (curLen > 0)
|
|
45686
45988
|
blocks.push(cur.digest("hex"));
|
|
45687
|
-
|
|
45989
|
+
resolve9({ wholeHash: whole.digest("hex"), blocks, size });
|
|
45688
45990
|
});
|
|
45689
45991
|
rs.on("error", reject);
|
|
45690
45992
|
});
|
|
@@ -45715,8 +46017,8 @@ var SendWindow = class {
|
|
|
45715
46017
|
wait() {
|
|
45716
46018
|
if (this.cancelled || this.sent - this.acked < this.maxInflight)
|
|
45717
46019
|
return Promise.resolve();
|
|
45718
|
-
return new Promise((
|
|
45719
|
-
this.wake =
|
|
46020
|
+
return new Promise((resolve9) => {
|
|
46021
|
+
this.wake = resolve9;
|
|
45720
46022
|
});
|
|
45721
46023
|
}
|
|
45722
46024
|
cancel() {
|
|
@@ -45765,7 +46067,7 @@ var StagingWriter = class {
|
|
|
45765
46067
|
}
|
|
45766
46068
|
async ensureOpen() {
|
|
45767
46069
|
if (!this.fh) {
|
|
45768
|
-
await
|
|
46070
|
+
await mkdir6(dirname9(this.stagingPath), { recursive: true });
|
|
45769
46071
|
this.fh = await open(this.stagingPath, "w");
|
|
45770
46072
|
}
|
|
45771
46073
|
return this.fh;
|
|
@@ -45795,7 +46097,7 @@ var StagingWriter = class {
|
|
|
45795
46097
|
});
|
|
45796
46098
|
await fh.close();
|
|
45797
46099
|
this.fh = null;
|
|
45798
|
-
await
|
|
46100
|
+
await mkdir6(dirname9(dest), { recursive: true });
|
|
45799
46101
|
await chmod2(this.stagingPath, mode & 511).catch(() => {
|
|
45800
46102
|
});
|
|
45801
46103
|
const secs = mtimeMs / 1e3;
|
|
@@ -45828,7 +46130,7 @@ var BlockAssembler = class {
|
|
|
45828
46130
|
this.stagingPath = stagingPath;
|
|
45829
46131
|
}
|
|
45830
46132
|
async open() {
|
|
45831
|
-
await
|
|
46133
|
+
await mkdir6(dirname9(this.stagingPath), { recursive: true });
|
|
45832
46134
|
this.fh = await open(this.stagingPath, "w");
|
|
45833
46135
|
}
|
|
45834
46136
|
/** Write a received block at its byte offset (index * CHUNK). */
|
|
@@ -45872,7 +46174,7 @@ var BlockAssembler = class {
|
|
|
45872
46174
|
});
|
|
45873
46175
|
return false;
|
|
45874
46176
|
}
|
|
45875
|
-
await
|
|
46177
|
+
await mkdir6(dirname9(dest), { recursive: true });
|
|
45876
46178
|
await chmod2(this.stagingPath, mode & 511).catch(() => {
|
|
45877
46179
|
});
|
|
45878
46180
|
const secs = mtimeMs / 1e3;
|
|
@@ -45895,8 +46197,8 @@ var BlockAssembler = class {
|
|
|
45895
46197
|
};
|
|
45896
46198
|
|
|
45897
46199
|
// ../../packages/host-core/dist/active-link/manifest.js
|
|
45898
|
-
import { readFileSync as
|
|
45899
|
-
import { join as
|
|
46200
|
+
import { readFileSync as readFileSync9, writeFileSync as writeFileSync8, mkdirSync as mkdirSync7, existsSync as existsSync11, renameSync as renameSync5 } from "node:fs";
|
|
46201
|
+
import { join as join20 } from "node:path";
|
|
45900
46202
|
|
|
45901
46203
|
// ../../packages/host-core/dist/active-link/reconcile.js
|
|
45902
46204
|
var ABSENT = { kind: "absent", t: -Infinity, hash: "" };
|
|
@@ -45932,11 +46234,11 @@ var LinkManifest = class {
|
|
|
45932
46234
|
this.dir = dir;
|
|
45933
46235
|
}
|
|
45934
46236
|
file() {
|
|
45935
|
-
return
|
|
46237
|
+
return join20(this.dir, "manifest.json");
|
|
45936
46238
|
}
|
|
45937
46239
|
load() {
|
|
45938
46240
|
try {
|
|
45939
|
-
const raw = JSON.parse(
|
|
46241
|
+
const raw = JSON.parse(readFileSync9(this.file(), "utf-8"));
|
|
45940
46242
|
this.records = new Map(Object.entries(raw.records ?? {}));
|
|
45941
46243
|
this.tombstones = new Map(Object.entries(raw.tombstones ?? {}));
|
|
45942
46244
|
} catch {
|
|
@@ -46034,7 +46336,7 @@ var LinkManifest = class {
|
|
|
46034
46336
|
|
|
46035
46337
|
// ../../packages/host-core/dist/active-link/scanner.js
|
|
46036
46338
|
import { readdir as readdir4, lstat as lstat2, readlink as readlink2 } from "node:fs/promises";
|
|
46037
|
-
import { join as
|
|
46339
|
+
import { join as join21, sep as sep6 } from "node:path";
|
|
46038
46340
|
async function walkRels(root, extraIgnore) {
|
|
46039
46341
|
const out = [];
|
|
46040
46342
|
async function rec(dir) {
|
|
@@ -46049,7 +46351,7 @@ async function walkRels(root, extraIgnore) {
|
|
|
46049
46351
|
continue;
|
|
46050
46352
|
if (e.isDirectory() && HEAVY_DIRS.has(e.name))
|
|
46051
46353
|
continue;
|
|
46052
|
-
const abs =
|
|
46354
|
+
const abs = join21(dir, e.name);
|
|
46053
46355
|
if (extraIgnore?.(abs))
|
|
46054
46356
|
continue;
|
|
46055
46357
|
if (e.isDirectory())
|
|
@@ -46088,7 +46390,7 @@ async function scanTree(root, prior, allow, extraIgnore) {
|
|
|
46088
46390
|
return { records };
|
|
46089
46391
|
}
|
|
46090
46392
|
function absOf(root, rel) {
|
|
46091
|
-
return
|
|
46393
|
+
return join21(root, rel.split("/").join(sep6));
|
|
46092
46394
|
}
|
|
46093
46395
|
|
|
46094
46396
|
// ../../packages/host-core/dist/active-link/gitignore.js
|
|
@@ -47151,7 +47453,7 @@ var NodeFsHandler = class {
|
|
|
47151
47453
|
this._addToNodeFs(path5, initialAdd, wh, depth + 1);
|
|
47152
47454
|
}
|
|
47153
47455
|
}).on(EV.ERROR, this._boundHandleError);
|
|
47154
|
-
return new Promise((
|
|
47456
|
+
return new Promise((resolve9, reject) => {
|
|
47155
47457
|
if (!stream)
|
|
47156
47458
|
return reject();
|
|
47157
47459
|
stream.once(STR_END, () => {
|
|
@@ -47160,7 +47462,7 @@ var NodeFsHandler = class {
|
|
|
47160
47462
|
return;
|
|
47161
47463
|
}
|
|
47162
47464
|
const wasThrottled = throttler ? throttler.clear() : false;
|
|
47163
|
-
|
|
47465
|
+
resolve9(void 0);
|
|
47164
47466
|
previous.getChildren().filter((item) => {
|
|
47165
47467
|
return item !== directory && !current.has(item);
|
|
47166
47468
|
}).forEach((item) => {
|
|
@@ -47304,11 +47606,11 @@ function createPattern(matcher) {
|
|
|
47304
47606
|
if (matcher.path === string4)
|
|
47305
47607
|
return true;
|
|
47306
47608
|
if (matcher.recursive) {
|
|
47307
|
-
const
|
|
47308
|
-
if (!
|
|
47609
|
+
const relative8 = sysPath2.relative(matcher.path, string4);
|
|
47610
|
+
if (!relative8) {
|
|
47309
47611
|
return false;
|
|
47310
47612
|
}
|
|
47311
|
-
return !
|
|
47613
|
+
return !relative8.startsWith("..") && !sysPath2.isAbsolute(relative8);
|
|
47312
47614
|
}
|
|
47313
47615
|
return false;
|
|
47314
47616
|
};
|
|
@@ -48016,8 +48318,8 @@ var LinkWatcher = class {
|
|
|
48016
48318
|
this.fsw.on("unlinkDir", onEvent);
|
|
48017
48319
|
this.fsw.on("error", () => {
|
|
48018
48320
|
});
|
|
48019
|
-
await new Promise((
|
|
48020
|
-
this.fsw.once("ready", () =>
|
|
48321
|
+
await new Promise((resolve9) => {
|
|
48322
|
+
this.fsw.once("ready", () => resolve9());
|
|
48021
48323
|
});
|
|
48022
48324
|
}
|
|
48023
48325
|
enqueue(abs) {
|
|
@@ -48105,7 +48407,7 @@ var ActiveLinkEngine = class {
|
|
|
48105
48407
|
}
|
|
48106
48408
|
async start() {
|
|
48107
48409
|
this.emit({ type: "status", linkId: this.opts.linkId, state: "scanning" });
|
|
48108
|
-
await rm3(
|
|
48410
|
+
await rm3(join24(this.stateDir, ".staging"), { recursive: true, force: true }).catch(() => {
|
|
48109
48411
|
});
|
|
48110
48412
|
this.manifest.load();
|
|
48111
48413
|
await this.reconcileScan();
|
|
@@ -48498,20 +48800,20 @@ var ActiveLinkEngine = class {
|
|
|
48498
48800
|
* file so the path still exists — recorded as a FILE matching disk so the local
|
|
48499
48801
|
* watcher doesn't churn. The target is containment-checked, never dereferenced. */
|
|
48500
48802
|
async applySymlink(rel, dest, target, mtimeMs, mode) {
|
|
48501
|
-
const resolved =
|
|
48803
|
+
const resolved = resolve7(dirname12(dest), target);
|
|
48502
48804
|
if (!isInsideRoot(resolved, this.opts.localRoot))
|
|
48503
48805
|
return;
|
|
48504
48806
|
const hash2 = hashString(target);
|
|
48505
48807
|
const secs = mtimeMs / 1e3;
|
|
48506
48808
|
try {
|
|
48507
|
-
await
|
|
48809
|
+
await mkdir7(dirname12(dest), { recursive: true });
|
|
48508
48810
|
await rm3(dest, { force: true, recursive: true });
|
|
48509
48811
|
try {
|
|
48510
48812
|
await symlink2(target, dest);
|
|
48511
48813
|
this.manifest.setRecord(rel, { kind: "symlink", mtimeMs, size: 0, mode, hash: hash2, blocks: [] });
|
|
48512
48814
|
} catch {
|
|
48513
48815
|
const buf = Buffer.from(target, "utf-8");
|
|
48514
|
-
await
|
|
48816
|
+
await writeFile5(dest, buf);
|
|
48515
48817
|
await utimes2(dest, secs, secs).catch(() => {
|
|
48516
48818
|
});
|
|
48517
48819
|
this.manifest.setRecord(rel, { kind: "file", mtimeMs, size: buf.length, mode, hash: hash2, blocks: [hash2] });
|
|
@@ -48554,7 +48856,7 @@ var ActiveLinkEngine = class {
|
|
|
48554
48856
|
return;
|
|
48555
48857
|
if (fromRec && fromRec.kind === "file") {
|
|
48556
48858
|
try {
|
|
48557
|
-
await
|
|
48859
|
+
await mkdir7(dirname12(toAbs), { recursive: true });
|
|
48558
48860
|
await rename2(fromAbs, toAbs);
|
|
48559
48861
|
const secs = mtimeMs / 1e3;
|
|
48560
48862
|
await utimes2(toAbs, secs, secs).catch(() => {
|
|
@@ -48729,7 +49031,7 @@ var ActiveLinkEngine = class {
|
|
|
48729
49031
|
this.inboundWatchdog.clear();
|
|
48730
49032
|
}
|
|
48731
49033
|
stagingPath(rel, tag) {
|
|
48732
|
-
return
|
|
49034
|
+
return join24(this.stateDir, ".staging", `${hashString(rel)}.${tag}`);
|
|
48733
49035
|
}
|
|
48734
49036
|
pruneSuppress() {
|
|
48735
49037
|
const now = this.now();
|
|
@@ -48754,14 +49056,14 @@ var ActiveLinkEngine = class {
|
|
|
48754
49056
|
};
|
|
48755
49057
|
|
|
48756
49058
|
// ../../packages/host-core/dist/active-link/config.js
|
|
48757
|
-
import { readFileSync as
|
|
48758
|
-
import { join as
|
|
49059
|
+
import { readFileSync as readFileSync10, writeFileSync as writeFileSync9, mkdirSync as mkdirSync8, existsSync as existsSync13, renameSync as renameSync6, watch as watch3 } from "node:fs";
|
|
49060
|
+
import { join as join25 } from "node:path";
|
|
48759
49061
|
function configPath2() {
|
|
48760
|
-
return
|
|
49062
|
+
return join25(activeLinkRoot(), "links.json");
|
|
48761
49063
|
}
|
|
48762
49064
|
function loadLinkConfigs() {
|
|
48763
49065
|
try {
|
|
48764
|
-
const raw = JSON.parse(
|
|
49066
|
+
const raw = JSON.parse(readFileSync10(configPath2(), "utf-8"));
|
|
48765
49067
|
if (!Array.isArray(raw.links))
|
|
48766
49068
|
return [];
|
|
48767
49069
|
return raw.links.filter((c) => c && c.linkId && c.localRoot && c.peerHostId);
|
|
@@ -48782,9 +49084,42 @@ function writeAll(links) {
|
|
|
48782
49084
|
}
|
|
48783
49085
|
function saveLinkConfig(cfg2) {
|
|
48784
49086
|
const links = loadLinkConfigs().filter((c) => c.linkId !== cfg2.linkId);
|
|
48785
|
-
links.push({
|
|
49087
|
+
links.push({
|
|
49088
|
+
linkId: cfg2.linkId,
|
|
49089
|
+
localRoot: cfg2.localRoot,
|
|
49090
|
+
peerHostId: cfg2.peerHostId,
|
|
49091
|
+
...cfg2.initiated ? { initiated: true } : {},
|
|
49092
|
+
...cfg2.workspaceLinkId ? { workspaceLinkId: cfg2.workspaceLinkId } : {},
|
|
49093
|
+
...cfg2.remoteParent ? { remoteParent: cfg2.remoteParent } : {},
|
|
49094
|
+
...cfg2.remoteSubfolder ? { remoteSubfolder: cfg2.remoteSubfolder } : {}
|
|
49095
|
+
});
|
|
48786
49096
|
writeAll(links);
|
|
48787
49097
|
}
|
|
49098
|
+
function pendingPath() {
|
|
49099
|
+
return join25(activeLinkRoot(), "pending-deprovisions.json");
|
|
49100
|
+
}
|
|
49101
|
+
function loadPendingDeprovisions() {
|
|
49102
|
+
try {
|
|
49103
|
+
const raw = JSON.parse(readFileSync10(pendingPath(), "utf-8"));
|
|
49104
|
+
return Array.isArray(raw.pending) ? raw.pending.filter((p) => p && p.linkId && p.peerHostId) : [];
|
|
49105
|
+
} catch {
|
|
49106
|
+
return [];
|
|
49107
|
+
}
|
|
49108
|
+
}
|
|
49109
|
+
function writePending(pending) {
|
|
49110
|
+
try {
|
|
49111
|
+
const dir = activeLinkRoot();
|
|
49112
|
+
if (!existsSync13(dir))
|
|
49113
|
+
mkdirSync8(dir, { recursive: true });
|
|
49114
|
+
const tmp = `${pendingPath()}.tmp`;
|
|
49115
|
+
writeFileSync9(tmp, JSON.stringify({ pending }, null, 2));
|
|
49116
|
+
renameSync6(tmp, pendingPath());
|
|
49117
|
+
} catch {
|
|
49118
|
+
}
|
|
49119
|
+
}
|
|
49120
|
+
function removePendingDeprovision(linkId) {
|
|
49121
|
+
writePending(loadPendingDeprovisions().filter((p) => p.linkId !== linkId));
|
|
49122
|
+
}
|
|
48788
49123
|
function removeLinkConfig(linkId) {
|
|
48789
49124
|
writeAll(loadLinkConfigs().filter((c) => c.linkId !== linkId));
|
|
48790
49125
|
}
|
|
@@ -49437,6 +49772,7 @@ function resumeActiveLinks() {
|
|
|
49437
49772
|
if (cfg2.initiated && isHostOnline(cfg2.peerHostId))
|
|
49438
49773
|
sendActiveLinkProvision(cfg2);
|
|
49439
49774
|
}
|
|
49775
|
+
flushPendingDeprovisions();
|
|
49440
49776
|
} catch (e) {
|
|
49441
49777
|
console.warn("[active-link] resume failed:", e.message);
|
|
49442
49778
|
}
|
|
@@ -49445,11 +49781,21 @@ function isHostOnline(hostId) {
|
|
|
49445
49781
|
return serverHosts.some((h) => h.hostId === hostId && h.online);
|
|
49446
49782
|
}
|
|
49447
49783
|
function sendActiveLinkProvision(cfg2) {
|
|
49448
|
-
send("activelink", {
|
|
49784
|
+
send("activelink", {
|
|
49785
|
+
type: "provision",
|
|
49786
|
+
linkId: cfg2.linkId,
|
|
49787
|
+
fromHost: ownHostId(),
|
|
49788
|
+
projectName: cfg2.remoteSubfolder ?? basename5(cfg2.localRoot),
|
|
49789
|
+
...cfg2.remoteParent ? { remoteParent: cfg2.remoteParent } : {},
|
|
49790
|
+
...cfg2.remoteSubfolder ? { remoteSubfolder: cfg2.remoteSubfolder } : {},
|
|
49791
|
+
...cfg2.workspaceLinkId ? { workspaceLinkId: cfg2.workspaceLinkId } : {}
|
|
49792
|
+
}, { hostId: cfg2.peerHostId });
|
|
49449
49793
|
}
|
|
49450
49794
|
function safeFolderName(name) {
|
|
49451
49795
|
const cleaned = name.replace(/[/\\]/g, "-").replace(/\.\.+/g, ".").trim();
|
|
49452
|
-
|
|
49796
|
+
if (!cleaned || /^\.+$/.test(cleaned))
|
|
49797
|
+
return "project";
|
|
49798
|
+
return cleaned;
|
|
49453
49799
|
}
|
|
49454
49800
|
function provisionActiveLinkMirror(payload) {
|
|
49455
49801
|
if (!activeLinkEnabled())
|
|
@@ -49461,9 +49807,17 @@ function provisionActiveLinkMirror(payload) {
|
|
|
49461
49807
|
resumeActiveLinks();
|
|
49462
49808
|
return;
|
|
49463
49809
|
}
|
|
49464
|
-
|
|
49810
|
+
const workspaceLinkId = typeof payload.workspaceLinkId === "string" ? payload.workspaceLinkId : void 0;
|
|
49811
|
+
const remoteParent = typeof payload.remoteParent === "string" ? payload.remoteParent : void 0;
|
|
49812
|
+
const remoteSubfolder = typeof payload.remoteSubfolder === "string" ? payload.remoteSubfolder : void 0;
|
|
49813
|
+
let localRoot;
|
|
49814
|
+
if (remoteParent && remoteSubfolder) {
|
|
49815
|
+
localRoot = join26(remoteParent, safeFolderName(remoteSubfolder));
|
|
49816
|
+
} else {
|
|
49817
|
+
localRoot = join26(HOST_ROOT, "Tesseract Mirrors", safeFolderName(projectName));
|
|
49818
|
+
}
|
|
49465
49819
|
if (loadLinkConfigs().some((c) => c.localRoot === localRoot && c.linkId !== linkId)) {
|
|
49466
|
-
localRoot =
|
|
49820
|
+
localRoot = `${localRoot}-${linkId.slice(0, 6)}`;
|
|
49467
49821
|
}
|
|
49468
49822
|
if (!isInsideRoot(localRoot, HOST_ROOT))
|
|
49469
49823
|
return;
|
|
@@ -49471,9 +49825,31 @@ function provisionActiveLinkMirror(payload) {
|
|
|
49471
49825
|
mkdirSync9(localRoot, { recursive: true });
|
|
49472
49826
|
} catch {
|
|
49473
49827
|
}
|
|
49474
|
-
saveLinkConfig({
|
|
49828
|
+
saveLinkConfig({
|
|
49829
|
+
linkId,
|
|
49830
|
+
localRoot,
|
|
49831
|
+
peerHostId: fromHost,
|
|
49832
|
+
...workspaceLinkId ? { workspaceLinkId } : {},
|
|
49833
|
+
...remoteParent ? { remoteParent } : {},
|
|
49834
|
+
...remoteSubfolder ? { remoteSubfolder } : {}
|
|
49835
|
+
});
|
|
49475
49836
|
resumeActiveLinks();
|
|
49476
49837
|
}
|
|
49838
|
+
function flushPendingDeprovisions() {
|
|
49839
|
+
for (const d of loadPendingDeprovisions()) {
|
|
49840
|
+
if (isHostOnline(d.peerHostId))
|
|
49841
|
+
send("activelink", { type: "deprovision", linkId: d.linkId, fromHost: ownHostId() }, { hostId: d.peerHostId });
|
|
49842
|
+
}
|
|
49843
|
+
}
|
|
49844
|
+
function deprovisionActiveLinkMirror(payload) {
|
|
49845
|
+
const { linkId, fromHost } = payload;
|
|
49846
|
+
if (typeof linkId !== "string")
|
|
49847
|
+
return;
|
|
49848
|
+
void disconnectActiveLink(linkId);
|
|
49849
|
+
removeLinkConfig(linkId);
|
|
49850
|
+
if (typeof fromHost === "string")
|
|
49851
|
+
send("activelink", { type: "deprovisionAck", linkId }, { hostId: fromHost });
|
|
49852
|
+
}
|
|
49477
49853
|
function handleActiveLinkChannel(payload, inbound) {
|
|
49478
49854
|
if (!inbound)
|
|
49479
49855
|
return;
|
|
@@ -49481,8 +49857,12 @@ function handleActiveLinkChannel(payload, inbound) {
|
|
|
49481
49857
|
const p = payload;
|
|
49482
49858
|
if (p?.type === "provision")
|
|
49483
49859
|
provisionActiveLinkMirror(p);
|
|
49860
|
+
else if (p?.type === "deprovision")
|
|
49861
|
+
deprovisionActiveLinkMirror(p);
|
|
49862
|
+
else if (p?.type === "deprovisionAck" && typeof p.linkId === "string")
|
|
49863
|
+
removePendingDeprovision(p.linkId);
|
|
49484
49864
|
} catch (e) {
|
|
49485
|
-
console.warn("[active-link]
|
|
49865
|
+
console.warn("[active-link] channel handler failed:", e.message);
|
|
49486
49866
|
}
|
|
49487
49867
|
}
|
|
49488
49868
|
async function beginOutboundTransfer(p, clientId) {
|
|
@@ -49498,8 +49878,8 @@ async function beginOutboundTransfer(p, clientId) {
|
|
|
49498
49878
|
}
|
|
49499
49879
|
var fsWaiters = /* @__PURE__ */ new Map();
|
|
49500
49880
|
function rejectAllFsWaiters() {
|
|
49501
|
-
for (const [,
|
|
49502
|
-
|
|
49881
|
+
for (const [, resolve9] of fsWaiters)
|
|
49882
|
+
resolve9({ error: "Disconnected from the remote machine." });
|
|
49503
49883
|
fsWaiters.clear();
|
|
49504
49884
|
}
|
|
49505
49885
|
function clientIdFor(msg) {
|
|
@@ -49834,7 +50214,8 @@ function stopHeartbeat() {
|
|
|
49834
50214
|
function registerAsHost() {
|
|
49835
50215
|
void ensureP2pReady();
|
|
49836
50216
|
const kind = process.env.CCB_HOST_KIND === "cloud" ? "cloud" : void 0;
|
|
49837
|
-
|
|
50217
|
+
const name = kind === "cloud" ? "Cloud agent" : hostname3();
|
|
50218
|
+
send("host", { type: "host:register", name, platform: process.platform, deviceId, caps: ["agent", "fs", "term"], ...kind ? { kind } : {}, ...staticMetrics(hostVersion), ...p2pAdvert ?? {} });
|
|
49838
50219
|
if (!heartbeat)
|
|
49839
50220
|
heartbeat = setInterval(() => send("host", { type: "host:heartbeat", ...dynamicMetrics() }), 2e4);
|
|
49840
50221
|
}
|
|
@@ -50132,8 +50513,8 @@ async function startLocalServer(opts) {
|
|
|
50132
50513
|
const log3 = opts.log ?? (() => {
|
|
50133
50514
|
});
|
|
50134
50515
|
const wss = new import_websocket_server.default({ host: "127.0.0.1", port: 0 });
|
|
50135
|
-
await new Promise((
|
|
50136
|
-
wss.once("listening",
|
|
50516
|
+
await new Promise((resolve9, reject) => {
|
|
50517
|
+
wss.once("listening", resolve9);
|
|
50137
50518
|
wss.once("error", reject);
|
|
50138
50519
|
});
|
|
50139
50520
|
const addr = wss.address();
|
|
@@ -50368,8 +50749,8 @@ async function startLocalServer(opts) {
|
|
|
50368
50749
|
}
|
|
50369
50750
|
|
|
50370
50751
|
// ../../packages/host-core/dist/daemon-runtime.js
|
|
50371
|
-
import { readFileSync as
|
|
50372
|
-
import { join as
|
|
50752
|
+
import { readFileSync as readFileSync11, writeFileSync as writeFileSync10, existsSync as existsSync15, mkdirSync as mkdirSync10, unlinkSync as unlinkSync2, chmodSync as chmodSync3 } from "node:fs";
|
|
50753
|
+
import { join as join27 } from "node:path";
|
|
50373
50754
|
import { homedir as homedir11 } from "node:os";
|
|
50374
50755
|
import { randomBytes as randomBytes3 } from "node:crypto";
|
|
50375
50756
|
|
|
@@ -50436,8 +50817,8 @@ async function runDaemon(opts = {}) {
|
|
|
50436
50817
|
const VERSION = opts.version ?? process.env.CCB_DAEMON_VERSION ?? "dev";
|
|
50437
50818
|
const TAG = opts.tag ?? "host-daemon";
|
|
50438
50819
|
const log3 = (...args) => console.log(`[${TAG} ${(/* @__PURE__ */ new Date()).toISOString()}]`, ...args);
|
|
50439
|
-
const pidfile = () =>
|
|
50440
|
-
const statusFile = () =>
|
|
50820
|
+
const pidfile = () => join27(daemonDir(), "daemon.lock");
|
|
50821
|
+
const statusFile = () => join27(daemonDir(), "status.json");
|
|
50441
50822
|
const isAlive2 = (pid) => {
|
|
50442
50823
|
try {
|
|
50443
50824
|
process.kill(pid, 0);
|
|
@@ -50450,7 +50831,7 @@ async function runDaemon(opts = {}) {
|
|
|
50450
50831
|
const f = pidfile();
|
|
50451
50832
|
try {
|
|
50452
50833
|
if (existsSync15(f)) {
|
|
50453
|
-
const prev = Number(
|
|
50834
|
+
const prev = Number(readFileSync11(f, "utf-8").trim());
|
|
50454
50835
|
if (prev && prev !== process.pid && isAlive2(prev))
|
|
50455
50836
|
return false;
|
|
50456
50837
|
}
|
|
@@ -50467,14 +50848,14 @@ async function runDaemon(opts = {}) {
|
|
|
50467
50848
|
function releaseLock() {
|
|
50468
50849
|
try {
|
|
50469
50850
|
const f = pidfile();
|
|
50470
|
-
if (existsSync15(f) && Number(
|
|
50851
|
+
if (existsSync15(f) && Number(readFileSync11(f, "utf-8").trim()) === process.pid)
|
|
50471
50852
|
unlinkSync2(f);
|
|
50472
50853
|
} catch {
|
|
50473
50854
|
}
|
|
50474
50855
|
}
|
|
50475
50856
|
function writeStatus(s) {
|
|
50476
50857
|
try {
|
|
50477
|
-
writeFileSync10(statusFile(), JSON.stringify({ pid: process.pid, version: VERSION, updatedAt: (/* @__PURE__ */ new Date()).toISOString(), ...localInfo ?? {}, ...s }));
|
|
50858
|
+
writeFileSync10(statusFile(), JSON.stringify({ pid: process.pid, version: VERSION, execPath: process.execPath, updatedAt: (/* @__PURE__ */ new Date()).toISOString(), ...localInfo ?? {}, ...s }));
|
|
50478
50859
|
chmodSync3(statusFile(), 384);
|
|
50479
50860
|
} catch {
|
|
50480
50861
|
}
|
|
@@ -50537,7 +50918,7 @@ async function runDaemon(opts = {}) {
|
|
|
50537
50918
|
if (r.status === 401) {
|
|
50538
50919
|
log3("device token no longer valid \u2014 dropping to local-only on restart");
|
|
50539
50920
|
try {
|
|
50540
|
-
unlinkSync2(
|
|
50921
|
+
unlinkSync2(join27(daemonDir(), "credentials.json"));
|
|
50541
50922
|
} catch {
|
|
50542
50923
|
}
|
|
50543
50924
|
shutdown(0);
|
|
@@ -50583,7 +50964,7 @@ import { platform as platform2 } from "node:os";
|
|
|
50583
50964
|
|
|
50584
50965
|
// ../../packages/host-core/dist/service/launchd.js
|
|
50585
50966
|
import { writeFileSync as writeFileSync11, existsSync as existsSync16, mkdirSync as mkdirSync11, unlinkSync as unlinkSync3 } from "node:fs";
|
|
50586
|
-
import { dirname as dirname13, join as
|
|
50967
|
+
import { dirname as dirname13, join as join28 } from "node:path";
|
|
50587
50968
|
import { homedir as homedir12, userInfo } from "node:os";
|
|
50588
50969
|
|
|
50589
50970
|
// ../../packages/host-core/dist/service/exec.js
|
|
@@ -50591,10 +50972,10 @@ import { execFile as execFile5, spawn as spawn5 } from "node:child_process";
|
|
|
50591
50972
|
import { promisify as promisify4 } from "node:util";
|
|
50592
50973
|
var run = promisify4(execFile5);
|
|
50593
50974
|
function runInherit(cmd, args) {
|
|
50594
|
-
return new Promise((
|
|
50975
|
+
return new Promise((resolve9) => {
|
|
50595
50976
|
const p = spawn5(cmd, args, { stdio: "inherit" });
|
|
50596
|
-
p.on("error", () =>
|
|
50597
|
-
p.on("close", () =>
|
|
50977
|
+
p.on("error", () => resolve9());
|
|
50978
|
+
p.on("close", () => resolve9());
|
|
50598
50979
|
});
|
|
50599
50980
|
}
|
|
50600
50981
|
|
|
@@ -50607,10 +50988,10 @@ function xml(s) {
|
|
|
50607
50988
|
}
|
|
50608
50989
|
function makeLaunchd(instanceId) {
|
|
50609
50990
|
const label = SERVICE_LABEL_BASE + (instanceId ? `.${instanceId}` : "");
|
|
50610
|
-
const plistPath = () =>
|
|
50991
|
+
const plistPath = () => join28(homedir12(), "Library", "LaunchAgents", `${label}.plist`);
|
|
50611
50992
|
const domainTarget = () => `gui/${userInfo().uid}`;
|
|
50612
50993
|
const serviceTarget = () => `${domainTarget()}/${label}`;
|
|
50613
|
-
const logFile = () =>
|
|
50994
|
+
const logFile = () => join28(daemonDir(), "daemon.log");
|
|
50614
50995
|
function buildPlist(spec) {
|
|
50615
50996
|
const args = [spec.exec, ...spec.args].map((a) => ` <string>${xml(a)}</string>`).join("\n");
|
|
50616
50997
|
const env = Object.entries(spec.env).map(([k, v]) => ` <key>${xml(k)}</key>
|
|
@@ -50703,7 +51084,7 @@ ${env}
|
|
|
50703
51084
|
|
|
50704
51085
|
// ../../packages/host-core/dist/service/systemd.js
|
|
50705
51086
|
import { writeFileSync as writeFileSync12, existsSync as existsSync17, mkdirSync as mkdirSync12, unlinkSync as unlinkSync4 } from "node:fs";
|
|
50706
|
-
import { dirname as dirname14, join as
|
|
51087
|
+
import { dirname as dirname14, join as join29 } from "node:path";
|
|
50707
51088
|
import { homedir as homedir13, userInfo as userInfo2 } from "node:os";
|
|
50708
51089
|
function shq(s) {
|
|
50709
51090
|
return `"${s.replace(/(["\\$`])/g, "\\$1")}"`;
|
|
@@ -50711,8 +51092,8 @@ function shq(s) {
|
|
|
50711
51092
|
function makeSystemd(instanceId) {
|
|
50712
51093
|
const unit = `tesseract-host${instanceId ? `-${instanceId}` : ""}.service`;
|
|
50713
51094
|
const unitPath = () => {
|
|
50714
|
-
const base = process.env.XDG_CONFIG_HOME ||
|
|
50715
|
-
return
|
|
51095
|
+
const base = process.env.XDG_CONFIG_HOME || join29(homedir13(), ".config");
|
|
51096
|
+
return join29(base, "systemd", "user", unit);
|
|
50716
51097
|
};
|
|
50717
51098
|
function buildUnit(spec) {
|
|
50718
51099
|
const execStart = [spec.exec, ...spec.args].map(shq).join(" ");
|
|
@@ -50783,11 +51164,11 @@ WantedBy=default.target
|
|
|
50783
51164
|
|
|
50784
51165
|
// ../../packages/host-core/dist/service/windows.js
|
|
50785
51166
|
import { writeFileSync as writeFileSync13, existsSync as existsSync18, mkdirSync as mkdirSync13, unlinkSync as unlinkSync5 } from "node:fs";
|
|
50786
|
-
import { dirname as dirname15, join as
|
|
51167
|
+
import { dirname as dirname15, join as join30 } from "node:path";
|
|
50787
51168
|
function makeWindowsTask(instanceId) {
|
|
50788
51169
|
const task = `Fineguide\\TesseractHost${instanceId ? `-${instanceId}` : ""}`;
|
|
50789
|
-
const wrapperPath = () =>
|
|
50790
|
-
const logFile = () =>
|
|
51170
|
+
const wrapperPath = () => join30(daemonDir(), `run-host${instanceId ? `-${instanceId}` : ""}.cmd`);
|
|
51171
|
+
const logFile = () => join30(daemonDir(), "daemon.log");
|
|
50791
51172
|
function buildWrapper(spec) {
|
|
50792
51173
|
const env = Object.entries(spec.env).map(([k, v]) => `set "${k}=${v}"`).join("\r\n");
|
|
50793
51174
|
const cmd = [spec.exec, ...spec.args].map((a) => `"${a}"`).join(" ");
|
|
@@ -50866,7 +51247,7 @@ function getServiceController(instanceId) {
|
|
|
50866
51247
|
var import_qrcode_terminal = __toESM(require_main(), 1);
|
|
50867
51248
|
import { randomUUID as randomUUID6 } from "node:crypto";
|
|
50868
51249
|
import { existsSync as existsSync19, rmSync } from "node:fs";
|
|
50869
|
-
import { join as
|
|
51250
|
+
import { join as join31 } from "node:path";
|
|
50870
51251
|
|
|
50871
51252
|
// src/config.ts
|
|
50872
51253
|
import { hostname as hostname4 } from "node:os";
|
|
@@ -50898,7 +51279,7 @@ var BS = String.fromCharCode(8);
|
|
|
50898
51279
|
var ERASE = BS + " " + BS;
|
|
50899
51280
|
function ask(question) {
|
|
50900
51281
|
const { stdin, stdout } = process;
|
|
50901
|
-
return new Promise((
|
|
51282
|
+
return new Promise((resolve9) => {
|
|
50902
51283
|
stdout.write(question);
|
|
50903
51284
|
stdin.setEncoding("utf8");
|
|
50904
51285
|
if (!stdin.isTTY || typeof stdin.setRawMode !== "function") {
|
|
@@ -50911,7 +51292,7 @@ function ask(question) {
|
|
|
50911
51292
|
stdin.pause();
|
|
50912
51293
|
let line = data.slice(0, nl);
|
|
50913
51294
|
if (line.endsWith(CR)) line = line.slice(0, -1);
|
|
50914
|
-
|
|
51295
|
+
resolve9(line.trim());
|
|
50915
51296
|
}
|
|
50916
51297
|
};
|
|
50917
51298
|
stdin.resume();
|
|
@@ -50926,7 +51307,7 @@ function ask(question) {
|
|
|
50926
51307
|
stdin.pause();
|
|
50927
51308
|
stdin.removeListener("data", onData);
|
|
50928
51309
|
stdout.write(LF);
|
|
50929
|
-
|
|
51310
|
+
resolve9(buf.trim());
|
|
50930
51311
|
}
|
|
50931
51312
|
function onData(chunk) {
|
|
50932
51313
|
for (const ch of chunk) {
|
|
@@ -50982,7 +51363,7 @@ function persist2(api, relay, deviceId2, dt) {
|
|
|
50982
51363
|
async function login(opts) {
|
|
50983
51364
|
const api = (opts.api ?? DEFAULT_API).replace(/\/$/, "");
|
|
50984
51365
|
const relay = (opts.relay ?? defaultRelay(api)).replace(/\/$/, "");
|
|
50985
|
-
const deviceId2 = readCredentials()?.deviceId ?? randomUUID6().slice(0, 8);
|
|
51366
|
+
const deviceId2 = readCredentials()?.deviceId ?? process.env.CCB_DEVICE_ID ?? randomUUID6().slice(0, 8);
|
|
50986
51367
|
const label = opts.name ?? defaultLabel();
|
|
50987
51368
|
if (opts.token) {
|
|
50988
51369
|
const dt = await fetchJson(`${api}/auth/device-token`, {
|
|
@@ -51043,7 +51424,7 @@ async function logout() {
|
|
|
51043
51424
|
}
|
|
51044
51425
|
for (const f of ["credentials.json", "status.json", "daemon.lock"]) {
|
|
51045
51426
|
try {
|
|
51046
|
-
const p =
|
|
51427
|
+
const p = join31(daemonDir(), f);
|
|
51047
51428
|
if (existsSync19(p)) rmSync(p);
|
|
51048
51429
|
} catch {
|
|
51049
51430
|
}
|
|
@@ -51105,7 +51486,7 @@ async function fetchLatest() {
|
|
|
51105
51486
|
}
|
|
51106
51487
|
}
|
|
51107
51488
|
function installVersion(target) {
|
|
51108
|
-
return new Promise((
|
|
51489
|
+
return new Promise((resolve9) => {
|
|
51109
51490
|
const npm = process.platform === "win32" ? "npm.cmd" : "npm";
|
|
51110
51491
|
log2(`installing tesseract-agent@${target} \u2026`);
|
|
51111
51492
|
let child;
|
|
@@ -51113,20 +51494,20 @@ function installVersion(target) {
|
|
|
51113
51494
|
child = spawn6(npm, ["install", "-g", `tesseract-agent@${target}`], { stdio: ["ignore", "inherit", "inherit"] });
|
|
51114
51495
|
} catch (e) {
|
|
51115
51496
|
log2("npm spawn threw:", e instanceof Error ? e.message : String(e));
|
|
51116
|
-
|
|
51497
|
+
resolve9(false);
|
|
51117
51498
|
return;
|
|
51118
51499
|
}
|
|
51119
51500
|
child.on("error", (e) => {
|
|
51120
51501
|
log2("npm not runnable:", e.message);
|
|
51121
|
-
|
|
51502
|
+
resolve9(false);
|
|
51122
51503
|
});
|
|
51123
51504
|
child.on("close", (code) => {
|
|
51124
51505
|
if (code === 0) {
|
|
51125
51506
|
log2(`installed ${target}`);
|
|
51126
|
-
|
|
51507
|
+
resolve9(true);
|
|
51127
51508
|
} else {
|
|
51128
51509
|
log2(`npm install exited ${code} \u2014 staying on the current version`);
|
|
51129
|
-
|
|
51510
|
+
resolve9(false);
|
|
51130
51511
|
}
|
|
51131
51512
|
});
|
|
51132
51513
|
});
|
|
@@ -51167,9 +51548,9 @@ function startSelfUpdater(current) {
|
|
|
51167
51548
|
}
|
|
51168
51549
|
|
|
51169
51550
|
// src/service.ts
|
|
51170
|
-
import { join as
|
|
51551
|
+
import { join as join32 } from "node:path";
|
|
51171
51552
|
import { platform as platform3 } from "node:os";
|
|
51172
|
-
import { existsSync as existsSync20, readFileSync as
|
|
51553
|
+
import { existsSync as existsSync20, readFileSync as readFileSync12 } from "node:fs";
|
|
51173
51554
|
function controller(instanceId) {
|
|
51174
51555
|
const c = getServiceController(instanceId);
|
|
51175
51556
|
if (!c) {
|
|
@@ -51182,7 +51563,7 @@ function buildSpec(cliEntry) {
|
|
|
51182
51563
|
exec: process.execPath,
|
|
51183
51564
|
args: [cliEntry, "run"],
|
|
51184
51565
|
env: { CCB_DAEMON_DIR: daemonDir() },
|
|
51185
|
-
logPath:
|
|
51566
|
+
logPath: join32(daemonDir(), "daemon.log")
|
|
51186
51567
|
};
|
|
51187
51568
|
}
|
|
51188
51569
|
var isAlive = (pid) => {
|
|
@@ -51194,10 +51575,10 @@ var isAlive = (pid) => {
|
|
|
51194
51575
|
}
|
|
51195
51576
|
};
|
|
51196
51577
|
function runningDaemonInfo() {
|
|
51197
|
-
const lock =
|
|
51578
|
+
const lock = join32(daemonDir(), "daemon.lock");
|
|
51198
51579
|
try {
|
|
51199
51580
|
if (!existsSync20(lock)) return null;
|
|
51200
|
-
const pid = Number(
|
|
51581
|
+
const pid = Number(readFileSync12(lock, "utf-8").trim());
|
|
51201
51582
|
if (!pid || !isAlive(pid)) return null;
|
|
51202
51583
|
return { pid, device: readCredentials()?.deviceId };
|
|
51203
51584
|
} catch {
|
|
@@ -51233,8 +51614,8 @@ async function logs(instanceId, follow) {
|
|
|
51233
51614
|
// src/cli.ts
|
|
51234
51615
|
function pkgVersion() {
|
|
51235
51616
|
try {
|
|
51236
|
-
const p =
|
|
51237
|
-
return JSON.parse(
|
|
51617
|
+
const p = join33(dirname16(fileURLToPath2(import.meta.url)), "..", "package.json");
|
|
51618
|
+
return JSON.parse(readFileSync13(p, "utf8")).version ?? "0.0.0";
|
|
51238
51619
|
} catch {
|
|
51239
51620
|
return "0.0.0";
|
|
51240
51621
|
}
|
|
@@ -51285,7 +51666,6 @@ function applyRunFlags(rest, flags) {
|
|
|
51285
51666
|
}
|
|
51286
51667
|
if (flags["no-active-link"] === true) process.env.CCB_ACTIVE_LINK = "0";
|
|
51287
51668
|
else if (flags["active-link"] === true) process.env.CCB_ACTIVE_LINK = "1";
|
|
51288
|
-
else if (process.env.CCB_ACTIVE_LINK === void 0) process.env.CCB_ACTIVE_LINK = "1";
|
|
51289
51669
|
}
|
|
51290
51670
|
async function superviseDaemon(cliEntry) {
|
|
51291
51671
|
let stopping = false;
|
|
@@ -51400,7 +51780,7 @@ async function linkCommand(rest, flags) {
|
|
|
51400
51780
|
return;
|
|
51401
51781
|
}
|
|
51402
51782
|
if (sub === "add") {
|
|
51403
|
-
const folder = rest[1] && !rest[1].startsWith("--") ?
|
|
51783
|
+
const folder = rest[1] && !rest[1].startsWith("--") ? resolve8(rest[1]) : void 0;
|
|
51404
51784
|
const peer = typeof flags.peer === "string" ? flags.peer : void 0;
|
|
51405
51785
|
if (!folder || !peer) {
|
|
51406
51786
|
console.error("Usage: tesseract-agent link add <folder> --peer <hostId> (--name <shared> | --id <sharedId>)");
|
|
@@ -51497,7 +51877,7 @@ async function main() {
|
|
|
51497
51877
|
process.exit(1);
|
|
51498
51878
|
}
|
|
51499
51879
|
instance = flags.instance;
|
|
51500
|
-
process.env.CCB_DAEMON_DIR =
|
|
51880
|
+
process.env.CCB_DAEMON_DIR = join33(homedir14(), ".tesseract", `daemon-${instance}`);
|
|
51501
51881
|
}
|
|
51502
51882
|
const force = flags.yes === true || flags.force === true;
|
|
51503
51883
|
const cliEntry = fileURLToPath2(import.meta.url);
|