blun-king-cli 9.1.613 → 9.1.615
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/CHANGELOG.md +14 -0
- package/LIESMICH.txt +1 -1
- package/README.md +1 -1
- package/agent-spine-plugin/src/lib/documents.js +1 -1
- package/agent-spine-plugin/src/lib/hook-context.js +1 -0
- package/agent-spine-plugin/src/lib/host-instruction-budget.js +1 -2
- package/agent-spine-plugin/src/lib/preflight.js +16 -5
- package/agent-spine-plugin/src/lib/source-roots.js +1 -1
- package/blun.mjs +1927 -1011
- package/bundled-agent-sources.json +5 -5
- package/codebase-index/codebase_index.py +25 -17
- package/package.json +1 -1
- package/telegram-plugin/dist/bridge.mjs +1 -200
- package/telegram-plugin/dist/mcp-server.mjs +8 -4
- package/worker-host.mjs +1215 -600
|
@@ -554,7 +554,7 @@
|
|
|
554
554
|
"agent-spine-plugin/src/lib/delivery-shell-wrapper.js": "95e178bcf8e1d7ea0bca58aa6aa5ea594bd15cac31f242e0e19250994732cd13",
|
|
555
555
|
"agent-spine-plugin/src/lib/delivery-target.js": "29109a53a1dc487e10a41315194c88c4d9d0b425a07420d3420166f9050aded6",
|
|
556
556
|
"agent-spine-plugin/src/lib/delivery-verification.js": "b9e094ebccf22a15e35505181b6968644087e455ec6826ba2c67ea61a5f2f5cc",
|
|
557
|
-
"agent-spine-plugin/src/lib/documents.js": "
|
|
557
|
+
"agent-spine-plugin/src/lib/documents.js": "49043da206c9948f4400048443772e891ee3367bc6a94e15a48df20f36c22870",
|
|
558
558
|
"agent-spine-plugin/src/lib/feed-transport.js": "5236f0a7010e6896dd1dc28eb56b7562d2c9037da171119bf2b3fe82b7055055",
|
|
559
559
|
"agent-spine-plugin/src/lib/filesystem-retry.js": "eba6335a068b0f5226e7c6b001b2dbadb294ad572098a2b713a3c78449ad785a",
|
|
560
560
|
"agent-spine-plugin/src/lib/gateway-common.js": "18b42c4e28963ecad64091f1b3416332aa829fe13d869efbe6b67c749e31992f",
|
|
@@ -580,7 +580,7 @@
|
|
|
580
580
|
"agent-spine-plugin/src/lib/hook-artifact-guards.js": "9e05895e9353afec815127322baccaed619969c752f6b00154354731afc8fac4",
|
|
581
581
|
"agent-spine-plugin/src/lib/hook-audit.js": "05dee25020febcf628f7474b48cb7cd94dab84dd0127394d6ac80a5a5c91312c",
|
|
582
582
|
"agent-spine-plugin/src/lib/hook-briefing-use.js": "ca4aed816d27f027bcc42600e80fa09d886d975d134a596c003f15603a381ed1",
|
|
583
|
-
"agent-spine-plugin/src/lib/hook-context.js": "
|
|
583
|
+
"agent-spine-plugin/src/lib/hook-context.js": "a2fe610207dbe8e5fb5455aa0d148df8f233fcbe025e8b1007379b875a1fc84a",
|
|
584
584
|
"agent-spine-plugin/src/lib/hook-final-message.js": "364044bba68c211a4b0f0474e5d77b6b3eb9db22fb64faea9bce623e4f4a4c9f",
|
|
585
585
|
"agent-spine-plugin/src/lib/hook-input.js": "61e7257a1b0e06072e6159cf47fad4c97c52d6d7261eafdf0a9ea7f839845891",
|
|
586
586
|
"agent-spine-plugin/src/lib/hook-output.js": "38a05c10e612f8aa449cca3ad25705491825c229191365e114a4978a2b8d32e9",
|
|
@@ -589,7 +589,7 @@
|
|
|
589
589
|
"agent-spine-plugin/src/lib/hook-protection.js": "9a42a3f86c92ae09a6b312faf3b9ea7bbe72e89dd227c3b3468d968cca36628f",
|
|
590
590
|
"agent-spine-plugin/src/lib/hook-stop-verification.js": "f6b4636b2136c8244f4f5deb8cd3fee6fd646b7d6b495093ff0c675411226eb2",
|
|
591
591
|
"agent-spine-plugin/src/lib/hook-timeline.js": "27fcdae15e3b35372f598ee30c1c6ae72afde377e684938fadf76b9fa7b8ee90",
|
|
592
|
-
"agent-spine-plugin/src/lib/host-instruction-budget.js": "
|
|
592
|
+
"agent-spine-plugin/src/lib/host-instruction-budget.js": "214bafaa4dc54405bea73ad78aeb63f78dd27ccd34a27fb4c2245f6c9f578cd0",
|
|
593
593
|
"agent-spine-plugin/src/lib/https-transport.js": "c3482f88851d6c04bffac160bfcc8fb447e8b188abf0e3a1ce5a4d25a3ce2307",
|
|
594
594
|
"agent-spine-plugin/src/lib/identifier-analysis.js": "a925db33ea8efabd3ce0a5fac1e74418b8a95c36fac1fedb4eaf846d0b4bcc76",
|
|
595
595
|
"agent-spine-plugin/src/lib/indexed-memory-offline.js": "0d4c14fcdabda4bbe35c20a5526c8511253839bb310c0c2bfb5dd1abc57e047c",
|
|
@@ -637,7 +637,7 @@
|
|
|
637
637
|
"agent-spine-plugin/src/lib/persona-runtime.js": "1f4c2f44edacc80bf92fc6906c78410ead0e379f2aaf34fed4bda55d4effe393",
|
|
638
638
|
"agent-spine-plugin/src/lib/pre-answer-timeline-recall.js": "50780f8f6ec1578fc06b82cf8f2902a203232964b6745d8155049f5284ff9221",
|
|
639
639
|
"agent-spine-plugin/src/lib/preflight-delivery-id.js": "d1467ac8278de877a44253428c7503991a08cc64f61ec6409f0f153535c7a2a6",
|
|
640
|
-
"agent-spine-plugin/src/lib/preflight.js": "
|
|
640
|
+
"agent-spine-plugin/src/lib/preflight.js": "d3ef8476146c825c110335b38e8fa37ae95313845384251d801df208698dd0e2",
|
|
641
641
|
"agent-spine-plugin/src/lib/project-portfolio.js": "9125715201d97b694827b400c8829cecfbbc142d01b19bd16f92915be08a904f",
|
|
642
642
|
"agent-spine-plugin/src/lib/runtime.js": "e9cb158700de18038651bbb21ac8211fcad8d50b016c7276dd078146a21f5555",
|
|
643
643
|
"agent-spine-plugin/src/lib/selfstarter-core.js": "428ab53db57163b53d6125df914fee14bfbdd555c761cf89993d273f4d92f5a9",
|
|
@@ -672,7 +672,7 @@
|
|
|
672
672
|
"agent-spine-plugin/src/lib/session-timeline-windows-acl.js": "e76fe7834ea45758c38aba39ebe956336785a8978a9edc79bd2873def6657b75",
|
|
673
673
|
"agent-spine-plugin/src/lib/session-timeline.js": "6f14664024b454c3186ecba0b1b4d3402b5fc1e491f7cf5a4787a7be22536c07",
|
|
674
674
|
"agent-spine-plugin/src/lib/sharing.js": "dee040d25122a39d3b44e752d1a22f64331c14bdd800f7b85cb9edc3ca9728b6",
|
|
675
|
-
"agent-spine-plugin/src/lib/source-roots.js": "
|
|
675
|
+
"agent-spine-plugin/src/lib/source-roots.js": "3091993a184e4eccbc08faedca8524810d2589cb606d3b8128a13968a27fc069",
|
|
676
676
|
"agent-spine-plugin/src/lib/source-tree-scan.js": "23bcac5c72aca9c43556fc606e5d37bde43c4ae8ee92017b02a8a5b7098fcbf3",
|
|
677
677
|
"agent-spine-plugin/src/lib/sqlite-transport.js": "5a329d4428c69e67fd56280b7258654572a792c0f03fb11e1f6a95ba8e0cf68a",
|
|
678
678
|
"agent-spine-plugin/src/lib/task-knowledge-context.js": "4163bde2cf3fdcc1b51b4981d4425e996a042a2295e123b5941f360da029e543",
|
|
@@ -7,7 +7,7 @@ Auflagen Dieter 43102:
|
|
|
7
7
|
(Run-3-Befund: Liste trieb RAM-Spitze auf 10,5 GB).
|
|
8
8
|
- Inkrementell: Content-Hash je Datei im Manifest, Delta statt Vollindex.
|
|
9
9
|
- Query mit Frische-Auskunft + Selbstauskunft in JEDER Antwort.
|
|
10
|
-
- Query-
|
|
10
|
+
- Lokales Query-Metadatenlog (query-log.jsonl), ohne Fragetext.
|
|
11
11
|
|
|
12
12
|
Aufruf:
|
|
13
13
|
python codebase_index.py build <repo>
|
|
@@ -351,13 +351,29 @@ def cmd_update(repo: str) -> None:
|
|
|
351
351
|
)
|
|
352
352
|
|
|
353
353
|
|
|
354
|
-
def freshness(repo: str, man: dict) -> str:
|
|
355
|
-
current = git_head(repo)
|
|
356
|
-
same = "== HEAD" if current == man["head"] else f"Index {man['head']} != HEAD {current} — 'update' faellig"
|
|
357
|
-
return f"Index-Stand: {man['head']} ({man['built_at']}), {man['chunks']} Chunks | {same}"
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
def
|
|
354
|
+
def freshness(repo: str, man: dict) -> str:
|
|
355
|
+
current = git_head(repo)
|
|
356
|
+
same = "== HEAD" if current == man["head"] else f"Index {man['head']} != HEAD {current} — 'update' faellig"
|
|
357
|
+
return f"Index-Stand: {man['head']} ({man['built_at']}), {man['chunks']} Chunks | {same}"
|
|
358
|
+
|
|
359
|
+
|
|
360
|
+
def append_query_metadata(dirpath: str, question: str, hits: list[tuple[str, float]],
|
|
361
|
+
requested_top: int, latency_ms: float, man: dict) -> None:
|
|
362
|
+
record = {
|
|
363
|
+
"ts": datetime.now(timezone.utc).isoformat(),
|
|
364
|
+
"query_bytes": len(question.encode("utf-8")),
|
|
365
|
+
"requested_top": requested_top,
|
|
366
|
+
"result_count": len(hits),
|
|
367
|
+
"result_paths": list(dict.fromkeys(meta.rsplit("#", 1)[0] for meta, _ in hits)),
|
|
368
|
+
"query_ms": round(latency_ms, 1),
|
|
369
|
+
"index_head": man["head"],
|
|
370
|
+
"model": man["model"],
|
|
371
|
+
}
|
|
372
|
+
with open(os.path.join(dirpath, "query-log.jsonl"), "a", encoding="utf-8") as fh:
|
|
373
|
+
fh.write(json.dumps(record) + "\n")
|
|
374
|
+
|
|
375
|
+
|
|
376
|
+
def cmd_query(repo: str, question: str, top: int, selector: str = "auto") -> int:
|
|
361
377
|
dirpath, man = resolve_existing_index(repo, selector)
|
|
362
378
|
activate_model(man["model"], man["dim"])
|
|
363
379
|
mat = np.load(os.path.join(dirpath, "vectors.npy"))
|
|
@@ -380,15 +396,7 @@ def cmd_query(repo: str, question: str, top: int, selector: str = "auto") -> int
|
|
|
380
396
|
print(f" {s:.4f} {m}")
|
|
381
397
|
print(f"query_ms={latency_ms:.1f}")
|
|
382
398
|
|
|
383
|
-
|
|
384
|
-
with open(log_path, "a", encoding="utf-8") as fh:
|
|
385
|
-
fh.write(json.dumps({
|
|
386
|
-
"ts": datetime.now(timezone.utc).isoformat(),
|
|
387
|
-
"query": question,
|
|
388
|
-
"top": hits,
|
|
389
|
-
"query_ms": round(latency_ms, 1),
|
|
390
|
-
"index_head": man["head"],
|
|
391
|
-
}) + "\n")
|
|
399
|
+
append_query_metadata(dirpath, question, hits, top, latency_ms, man)
|
|
392
400
|
return 0
|
|
393
401
|
|
|
394
402
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createRequire } from "node:module";
|
|
2
2
|
import { appendFileSync, chmodSync, closeSync, existsSync, fstatSync, lstatSync, mkdirSync, openSync, readFileSync, readSync, readdirSync, renameSync, rmSync, statSync, writeFileSync } from "node:fs";
|
|
3
3
|
import { dirname, join, resolve } from "node:path";
|
|
4
|
-
import { createHash,
|
|
4
|
+
import { createHash, randomBytes, randomUUID } from "node:crypto";
|
|
5
5
|
import { homedir } from "node:os";
|
|
6
6
|
import { spawn } from "node:child_process";
|
|
7
7
|
import { Readable, Writable } from "node:stream";
|
|
@@ -67686,204 +67686,6 @@ var RequestError = class RequestError extends Error {
|
|
|
67686
67686
|
}
|
|
67687
67687
|
};
|
|
67688
67688
|
//#endregion
|
|
67689
|
-
//#region src/language-release.ts
|
|
67690
|
-
const EXACT_LANGUAGE_TAG = /^(?:[A-Za-z]{2,8}|x)(?:-[A-Za-z0-9]{1,8})*$/;
|
|
67691
|
-
const LETTER = /^\p{Letter}$/u;
|
|
67692
|
-
const LATIN = /^\p{Script=Latin}$/u;
|
|
67693
|
-
const CYRILLIC = /^\p{Script=Cyrillic}$/u;
|
|
67694
|
-
const GREEK = /^\p{Script=Greek}$/u;
|
|
67695
|
-
const ARABIC = /^\p{Script=Arabic}$/u;
|
|
67696
|
-
const HEBREW = /^\p{Script=Hebrew}$/u;
|
|
67697
|
-
const HAN = /^\p{Script=Han}$/u;
|
|
67698
|
-
const HIRAGANA = /^\p{Script=Hiragana}$/u;
|
|
67699
|
-
const KATAKANA = /^\p{Script=Katakana}$/u;
|
|
67700
|
-
const HANGUL = /^\p{Script=Hangul}$/u;
|
|
67701
|
-
const LATIN_LANGUAGES = new Set([
|
|
67702
|
-
"af",
|
|
67703
|
-
"bs",
|
|
67704
|
-
"ca",
|
|
67705
|
-
"cs",
|
|
67706
|
-
"cy",
|
|
67707
|
-
"da",
|
|
67708
|
-
"de",
|
|
67709
|
-
"en",
|
|
67710
|
-
"es",
|
|
67711
|
-
"et",
|
|
67712
|
-
"eu",
|
|
67713
|
-
"fi",
|
|
67714
|
-
"fr",
|
|
67715
|
-
"ga",
|
|
67716
|
-
"gd",
|
|
67717
|
-
"gl",
|
|
67718
|
-
"hr",
|
|
67719
|
-
"hu",
|
|
67720
|
-
"id",
|
|
67721
|
-
"is",
|
|
67722
|
-
"it",
|
|
67723
|
-
"la",
|
|
67724
|
-
"lb",
|
|
67725
|
-
"lt",
|
|
67726
|
-
"lv",
|
|
67727
|
-
"ms",
|
|
67728
|
-
"mt",
|
|
67729
|
-
"nl",
|
|
67730
|
-
"no",
|
|
67731
|
-
"pl",
|
|
67732
|
-
"pt",
|
|
67733
|
-
"ro",
|
|
67734
|
-
"sk",
|
|
67735
|
-
"sl",
|
|
67736
|
-
"sq",
|
|
67737
|
-
"sv",
|
|
67738
|
-
"sw",
|
|
67739
|
-
"tr",
|
|
67740
|
-
"vi"
|
|
67741
|
-
]);
|
|
67742
|
-
function canonicalText(text) {
|
|
67743
|
-
return text.replace(/^\uFEFF/, "").replace(/\r\n?/g, "\n").normalize("NFC");
|
|
67744
|
-
}
|
|
67745
|
-
function canonicalHash(text) {
|
|
67746
|
-
return createHash("sha256").update(canonicalText(text), "utf8").digest("hex");
|
|
67747
|
-
}
|
|
67748
|
-
function maskTechnicalText(text) {
|
|
67749
|
-
const mask = (value) => " ".repeat(value.length);
|
|
67750
|
-
return text.replace(/```[\s\S]*?```|~~~[\s\S]*?~~~/g, mask).replace(/`[^`\r\n]*`/g, mask);
|
|
67751
|
-
}
|
|
67752
|
-
function allowedScriptMatchers(locale) {
|
|
67753
|
-
if (!EXACT_LANGUAGE_TAG.test(locale) || ["auto", "all"].includes(locale.toLowerCase())) throw new Error("language release blocked: exact output locale required");
|
|
67754
|
-
const parts = locale.replaceAll("_", "-").split("-");
|
|
67755
|
-
const base = parts[0]?.toLowerCase() ?? "";
|
|
67756
|
-
const explicitScript = parts.find((part) => part.length === 4)?.toLowerCase();
|
|
67757
|
-
if (explicitScript !== void 0) {
|
|
67758
|
-
const explicit = {
|
|
67759
|
-
latn: [LATIN],
|
|
67760
|
-
cyrl: [CYRILLIC],
|
|
67761
|
-
grek: [GREEK],
|
|
67762
|
-
arab: [ARABIC],
|
|
67763
|
-
hebr: [HEBREW],
|
|
67764
|
-
hani: [HAN],
|
|
67765
|
-
jpan: [
|
|
67766
|
-
HAN,
|
|
67767
|
-
HIRAGANA,
|
|
67768
|
-
KATAKANA
|
|
67769
|
-
],
|
|
67770
|
-
hang: [HANGUL, HAN]
|
|
67771
|
-
}[explicitScript];
|
|
67772
|
-
if (explicit === void 0) throw new Error("language release blocked: unsupported output script");
|
|
67773
|
-
return explicit;
|
|
67774
|
-
}
|
|
67775
|
-
if (LATIN_LANGUAGES.has(base)) return [LATIN];
|
|
67776
|
-
if ([
|
|
67777
|
-
"ru",
|
|
67778
|
-
"uk",
|
|
67779
|
-
"bg",
|
|
67780
|
-
"mk"
|
|
67781
|
-
].includes(base)) return [CYRILLIC];
|
|
67782
|
-
if (base === "el") return [GREEK];
|
|
67783
|
-
if ([
|
|
67784
|
-
"ar",
|
|
67785
|
-
"fa",
|
|
67786
|
-
"ur"
|
|
67787
|
-
].includes(base)) return [ARABIC];
|
|
67788
|
-
if (base === "he") return [HEBREW];
|
|
67789
|
-
if (base === "zh") return [HAN];
|
|
67790
|
-
if (base === "ja") return [
|
|
67791
|
-
HAN,
|
|
67792
|
-
HIRAGANA,
|
|
67793
|
-
KATAKANA
|
|
67794
|
-
];
|
|
67795
|
-
if (base === "ko") return [HANGUL, HAN];
|
|
67796
|
-
throw new Error("language release blocked: output locale has no deterministic script policy");
|
|
67797
|
-
}
|
|
67798
|
-
function assertExpectedScript(text, locale) {
|
|
67799
|
-
const allowed = allowedScriptMatchers(locale);
|
|
67800
|
-
for (const character of maskTechnicalText(text)) {
|
|
67801
|
-
if (!LETTER.test(character)) continue;
|
|
67802
|
-
if (allowed.some((matcher) => matcher.test(character))) continue;
|
|
67803
|
-
const point = character.codePointAt(0)?.toString(16).toUpperCase().padStart(4, "0") ?? "UNKNOWN";
|
|
67804
|
-
throw new Error(`language release blocked: unexpected-script-contamination (U+${point})`);
|
|
67805
|
-
}
|
|
67806
|
-
}
|
|
67807
|
-
function parseAndVerifySignature(token, key) {
|
|
67808
|
-
if (key.length < 32) throw new Error("language release blocked: invalid verification key");
|
|
67809
|
-
if (token.length > 16384) throw new Error("language release blocked: release token too large");
|
|
67810
|
-
const parts = token.split(".");
|
|
67811
|
-
if (parts.length !== 3 || parts[0] !== "blg6" || parts[1] === "" || parts[2] === "") throw new Error("language release blocked: malformed release token");
|
|
67812
|
-
const encoded = parts[1];
|
|
67813
|
-
let supplied;
|
|
67814
|
-
let payload;
|
|
67815
|
-
try {
|
|
67816
|
-
supplied = Buffer.from(parts[2], "base64url");
|
|
67817
|
-
payload = JSON.parse(Buffer.from(encoded, "base64url").toString("utf8"));
|
|
67818
|
-
} catch {
|
|
67819
|
-
throw new Error("language release blocked: malformed release token");
|
|
67820
|
-
}
|
|
67821
|
-
const expected = createHmac("sha256", key).update(encoded).digest();
|
|
67822
|
-
if (supplied.length !== expected.length || !timingSafeEqual(supplied, expected)) throw new Error("language release blocked: invalid release token signature");
|
|
67823
|
-
if (payload === null || typeof payload !== "object" || Array.isArray(payload)) throw new Error("language release blocked: malformed release payload");
|
|
67824
|
-
return payload;
|
|
67825
|
-
}
|
|
67826
|
-
function assertEqual(actual, expected, field) {
|
|
67827
|
-
if (actual !== expected) throw new Error(`language release blocked: ${field} mismatch`);
|
|
67828
|
-
}
|
|
67829
|
-
function verifyTelegramLanguageRelease(text, releaseToken, options) {
|
|
67830
|
-
if (typeof releaseToken !== "string" || releaseToken.length === 0) throw new Error("language release blocked: release token required");
|
|
67831
|
-
if (options.expectedVersion.trim().length === 0) throw new Error("language release blocked: expected guard version required");
|
|
67832
|
-
assertExpectedScript(text, options.locale);
|
|
67833
|
-
const payload = parseAndVerifySignature(releaseToken, options.key);
|
|
67834
|
-
const now = Math.floor(options.now ?? Date.now() / 1e3);
|
|
67835
|
-
if (!Number.isSafeInteger(payload.iat) || !Number.isSafeInteger(payload.exp)) throw new Error("language release blocked: invalid receipt lifetime");
|
|
67836
|
-
const issuedAt = payload.iat;
|
|
67837
|
-
const expiresAt = payload.exp;
|
|
67838
|
-
if (expiresAt < now) throw new Error("language release blocked: release token expired");
|
|
67839
|
-
if (issuedAt > now + 60 || expiresAt < issuedAt || expiresAt - issuedAt > 604800) throw new Error("language release blocked: invalid receipt lifetime");
|
|
67840
|
-
if (typeof payload.nonce !== "string" || payload.nonce.length === 0) throw new Error("language release blocked: invalid receipt nonce");
|
|
67841
|
-
assertEqual(payload.source_sha256, canonicalHash(""), "source");
|
|
67842
|
-
assertEqual(payload.target_sha256, canonicalHash(text), "target");
|
|
67843
|
-
if (payload.language !== options.locale) throw new Error(`language release blocked: language mismatch (expected ${options.locale})`);
|
|
67844
|
-
assertEqual(payload.purpose, "response", "purpose");
|
|
67845
|
-
assertEqual(payload.content_type, "prose", "content type");
|
|
67846
|
-
assertEqual(payload.short_text_reviewed, false, "short text review");
|
|
67847
|
-
assertEqual(payload.v, options.expectedVersion, "version");
|
|
67848
|
-
}
|
|
67849
|
-
function isLanguageReleaseRequired() {
|
|
67850
|
-
return process.env["BLUN_TELEGRAM_LANGUAGE_GATE"]?.trim().toLowerCase() === "required";
|
|
67851
|
-
}
|
|
67852
|
-
function requiredSetting(name) {
|
|
67853
|
-
const value = process.env[name]?.trim();
|
|
67854
|
-
if (value === void 0 || value.length === 0) throw new Error(`language release blocked: host setting ${name} required`);
|
|
67855
|
-
return value;
|
|
67856
|
-
}
|
|
67857
|
-
function telegramLanguageReleaseLocale() {
|
|
67858
|
-
if (!isLanguageReleaseRequired()) return void 0;
|
|
67859
|
-
const locale = requiredSetting("BLUN_TELEGRAM_OUTPUT_LOCALE");
|
|
67860
|
-
allowedScriptMatchers(locale);
|
|
67861
|
-
return locale;
|
|
67862
|
-
}
|
|
67863
|
-
function defaultKeyFile() {
|
|
67864
|
-
const configuredHome = process.env["BLUN_HOME"]?.trim();
|
|
67865
|
-
return join(configuredHome !== void 0 && configuredHome.length > 0 ? configuredHome : join(homedir(), ".blun"), "secrets", "blun-language-guard-signing.key");
|
|
67866
|
-
}
|
|
67867
|
-
function assertTelegramLanguageReleased(text, releaseToken, now) {
|
|
67868
|
-
if (!isLanguageReleaseRequired()) return;
|
|
67869
|
-
if (typeof releaseToken !== "string" || releaseToken.length === 0) throw new Error("language release blocked: release token required");
|
|
67870
|
-
const locale = telegramLanguageReleaseLocale();
|
|
67871
|
-
if (locale === void 0) throw new Error("language release blocked: exact output locale required");
|
|
67872
|
-
const keyFile = process.env["BLUN_LANGUAGE_GUARD_KEY_FILE"]?.trim() || defaultKeyFile();
|
|
67873
|
-
let key;
|
|
67874
|
-
try {
|
|
67875
|
-
key = readFileSync(keyFile);
|
|
67876
|
-
} catch {
|
|
67877
|
-
throw new Error("language release blocked: verification key unavailable");
|
|
67878
|
-
}
|
|
67879
|
-
verifyTelegramLanguageRelease(text, releaseToken, {
|
|
67880
|
-
locale,
|
|
67881
|
-
expectedVersion: requiredSetting("BLUN_LANGUAGE_GUARD_VERSION"),
|
|
67882
|
-
key,
|
|
67883
|
-
now
|
|
67884
|
-
});
|
|
67885
|
-
}
|
|
67886
|
-
//#endregion
|
|
67887
67689
|
//#region src/noise.ts
|
|
67888
67690
|
/**
|
|
67889
67691
|
* Conservative outbound guard for group acknowledgements and narrated silence.
|
|
@@ -68071,7 +67873,6 @@ async function sendReplyFallback(chatId, rawText, threadId) {
|
|
|
68071
67873
|
const text = scrubSecrets(rawText);
|
|
68072
67874
|
const body = text.length > TELEGRAM_TEXT_LIMIT ? `${text.slice(0, TELEGRAM_TEXT_LIMIT - 1)}…` : text;
|
|
68073
67875
|
try {
|
|
68074
|
-
assertTelegramLanguageReleased(body, void 0);
|
|
68075
67876
|
const payload = await (await fetch(`https://api.telegram.org/bot${token}/sendMessage`, {
|
|
68076
67877
|
method: "POST",
|
|
68077
67878
|
headers: { "Content-Type": "application/json" },
|
|
@@ -73449,6 +73449,10 @@ function assertTelegramLanguageReleased(text, releaseToken, now) {
|
|
|
73449
73449
|
now
|
|
73450
73450
|
});
|
|
73451
73451
|
}
|
|
73452
|
+
function assertOptionalTelegramLanguageRelease(text, releaseToken, now) {
|
|
73453
|
+
if (releaseToken === void 0) return;
|
|
73454
|
+
assertTelegramLanguageReleased(text, releaseToken, now);
|
|
73455
|
+
}
|
|
73452
73456
|
//#endregion
|
|
73453
73457
|
//#region src/noise.ts
|
|
73454
73458
|
/**
|
|
@@ -73528,7 +73532,7 @@ const TOOL_DEFINITIONS = [
|
|
|
73528
73532
|
text: { type: "string" },
|
|
73529
73533
|
release_token: {
|
|
73530
73534
|
type: "string",
|
|
73531
|
-
description: "Language Guard receipt for
|
|
73535
|
+
description: "Optional Language Guard receipt for released text. When provided, it must match this exact text."
|
|
73532
73536
|
},
|
|
73533
73537
|
reply_to: {
|
|
73534
73538
|
type: "string",
|
|
@@ -73592,7 +73596,7 @@ const TOOL_DEFINITIONS = [
|
|
|
73592
73596
|
text: { type: "string" },
|
|
73593
73597
|
release_token: {
|
|
73594
73598
|
type: "string",
|
|
73595
|
-
description: "Language Guard receipt for
|
|
73599
|
+
description: "Optional Language Guard receipt for released text. When provided, it must match this exact text."
|
|
73596
73600
|
},
|
|
73597
73601
|
format: {
|
|
73598
73602
|
type: "string",
|
|
@@ -73622,7 +73626,7 @@ async function runTool(api, token, name, args) {
|
|
|
73622
73626
|
case "edit_message": {
|
|
73623
73627
|
const chatId = resolveAllowedChatId(args["chat_id"]);
|
|
73624
73628
|
if (isSilentTurnMarker(args["text"])) throw new Error("silent marker cannot be used to edit a Telegram message");
|
|
73625
|
-
|
|
73629
|
+
assertOptionalTelegramLanguageRelease(args["text"], args["release_token"]);
|
|
73626
73630
|
const parseMode = args["format"] === "markdownv2" ? "MarkdownV2" : void 0;
|
|
73627
73631
|
const edited = await api.editMessageText(chatId, Number(args["message_id"]), args["text"], parseMode !== void 0 ? { parse_mode: parseMode } : void 0);
|
|
73628
73632
|
const id = typeof edited === "object" ? edited.message_id : args["message_id"];
|
|
@@ -73701,7 +73705,7 @@ async function runReply(api, args) {
|
|
|
73701
73705
|
});
|
|
73702
73706
|
return "already delivered: an identical message was sent to this chat moments ago — do NOT send it again";
|
|
73703
73707
|
}
|
|
73704
|
-
|
|
73708
|
+
assertOptionalTelegramLanguageRelease(text, args["release_token"]);
|
|
73705
73709
|
for (const file of files) {
|
|
73706
73710
|
assertSendable(file);
|
|
73707
73711
|
const info = statSync(file);
|