@securecoms/agent-bridge 0.30.2 → 0.30.3
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/README.md +37 -0
- package/dist/bin.js +248 -47
- package/dist/bridge-agent.d.ts +60 -0
- package/dist/consumer-grants.d.ts +15 -0
- package/dist/grants/binding.d.ts +30 -2
- package/dist/grants/manifest.d.ts +11 -1
- package/dist/grants/search-providers.d.ts +9 -0
- package/dist/http-server.d.ts +2 -0
- package/dist/index.js +227 -27
- package/dist/preflight-upgrade.d.cts +1 -0
- package/dist/preflight.cjs +1 -0
- package/dist/service/runtime-config-dir.d.ts +4 -0
- package/dist/version.d.ts +1 -1
- package/dist/ws-server.d.ts +1 -1
- package/package.json +1 -1
package/dist/bin.js
CHANGED
|
@@ -7556,7 +7556,7 @@ __export(import_bundle_exports, {
|
|
|
7556
7556
|
importModelBundle: () => importModelBundle
|
|
7557
7557
|
});
|
|
7558
7558
|
import { createHash as createHash6, randomBytes as randomBytes12 } from "node:crypto";
|
|
7559
|
-
import { readFileSync as
|
|
7559
|
+
import { readFileSync as readFileSync16, statSync as statSync7, writeFileSync as writeFileSync4 } from "node:fs";
|
|
7560
7560
|
import { join as join24 } from "node:path";
|
|
7561
7561
|
async function importModelBundle(srcDir, root3, m) {
|
|
7562
7562
|
const verified = [];
|
|
@@ -7574,7 +7574,7 @@ async function importModelBundle(srcDir, root3, m) {
|
|
|
7574
7574
|
if (size !== f.size) throw mismatch;
|
|
7575
7575
|
let bytes;
|
|
7576
7576
|
try {
|
|
7577
|
-
bytes =
|
|
7577
|
+
bytes = readFileSync16(src);
|
|
7578
7578
|
} catch {
|
|
7579
7579
|
throw new ModelImportError(`${f.name} is missing from the import directory`);
|
|
7580
7580
|
}
|
|
@@ -29882,7 +29882,7 @@ function loadPackageMeta(importMetaUrl) {
|
|
|
29882
29882
|
}
|
|
29883
29883
|
|
|
29884
29884
|
// src/bridge-agent.ts
|
|
29885
|
-
import { existsSync as existsSync5, promises as fsp, statSync as statSync5 } from "node:fs";
|
|
29885
|
+
import { existsSync as existsSync5, promises as fsp, readFileSync as readFileSync11, statSync as statSync5 } from "node:fs";
|
|
29886
29886
|
import { join as join19, dirname as dirname7 } from "node:path";
|
|
29887
29887
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
29888
29888
|
|
|
@@ -34397,6 +34397,15 @@ import {
|
|
|
34397
34397
|
writeFileSync
|
|
34398
34398
|
} from "node:fs";
|
|
34399
34399
|
import { basename as basename4, isAbsolute, join as join18 } from "node:path";
|
|
34400
|
+
|
|
34401
|
+
// src/grants/search-providers.ts
|
|
34402
|
+
var SEARCH_PROVIDERS = /* @__PURE__ */ new Set(["brave", "tavily", "parallel", "exa", "firecrawl"]);
|
|
34403
|
+
var OWNER_DM_SEARCH_DAILY_CAP_MAX = 2e3;
|
|
34404
|
+
function isSearchProvider(value) {
|
|
34405
|
+
return typeof value === "string" && SEARCH_PROVIDERS.has(value);
|
|
34406
|
+
}
|
|
34407
|
+
|
|
34408
|
+
// src/service/runtime-config-dir.ts
|
|
34400
34409
|
var MEMORY_FILE = "MEMORY.md";
|
|
34401
34410
|
var REAL_FS = {
|
|
34402
34411
|
mkdir: (p, mode) => mkdirSync5(p, { recursive: true, mode }),
|
|
@@ -34579,10 +34588,14 @@ function readLocalReport(home, identityId) {
|
|
|
34579
34588
|
const persona = raw && typeof raw === "object" && !Array.isArray(raw) ? Object.fromEntries(
|
|
34580
34589
|
Object.entries(raw).filter(([, v]) => typeof v === "string")
|
|
34581
34590
|
) : {};
|
|
34591
|
+
const capRaw = doc.owner_dm_search_cap_effective;
|
|
34592
|
+
const ownerDmCap = typeof capRaw === "number" && Number.isInteger(capRaw) && capRaw >= 0 && capRaw <= OWNER_DM_SEARCH_DAILY_CAP_MAX ? capRaw : void 0;
|
|
34582
34593
|
return {
|
|
34583
34594
|
persona,
|
|
34584
34595
|
has_search_key: hasSearchKey,
|
|
34585
34596
|
has_llm_key: hasLlmKey,
|
|
34597
|
+
has_extract_provider: doc.has_extract_provider === true,
|
|
34598
|
+
...ownerDmCap !== void 0 ? { owner_dm_search_cap_effective: ownerDmCap } : {},
|
|
34586
34599
|
legacy_memory: localLegacySources(doc).map(({ path: _path, ...source }) => source),
|
|
34587
34600
|
secret_paths: parseSecretPathsReport(doc.secret_paths)
|
|
34588
34601
|
};
|
|
@@ -34700,7 +34713,8 @@ import { sha256 as sha25611 } from "@noble/hashes/sha256";
|
|
|
34700
34713
|
import { ed25519 as ed255195 } from "@noble/curves/ed25519";
|
|
34701
34714
|
var TOOL_GRANTS_DOMAIN = "SECURECOMS-TOOL-GRANTS-V1:";
|
|
34702
34715
|
var MANIFEST_KNOWN_TOOLS = Object.freeze({
|
|
34703
|
-
owner_dm: Object.freeze(["web_search", "fetch_url", "http_request", "sql_query"]),
|
|
34716
|
+
owner_dm: Object.freeze(["web_search", "web_extract", "fetch_url", "http_request", "sql_query"]),
|
|
34717
|
+
// web_extract: owner DM only, never team_room (spec §5.4, D5)
|
|
34704
34718
|
team_room: Object.freeze(["web_search"])
|
|
34705
34719
|
});
|
|
34706
34720
|
function manifestSignedBytes(manifest) {
|
|
@@ -34775,7 +34789,11 @@ function parseConfig(v) {
|
|
|
34775
34789
|
}
|
|
34776
34790
|
if ("search" in v) {
|
|
34777
34791
|
const sr = v.search;
|
|
34778
|
-
if (!isPlainObject(sr) || !exactKeys(sr, ["provider"]
|
|
34792
|
+
if (!isPlainObject(sr) || !exactKeys(sr, ["provider"], ["owner_dm_daily_cap"]) || !isSearchProvider(sr.provider)) return null;
|
|
34793
|
+
if ("owner_dm_daily_cap" in sr) {
|
|
34794
|
+
const cap = sr.owner_dm_daily_cap;
|
|
34795
|
+
if (typeof cap !== "number" || !Number.isSafeInteger(cap) || cap < 0 || cap > OWNER_DM_SEARCH_DAILY_CAP_MAX) return null;
|
|
34796
|
+
}
|
|
34779
34797
|
}
|
|
34780
34798
|
const mem = v.memory;
|
|
34781
34799
|
if (!isPlainObject(mem) || !exactKeys(mem, ["mode"], ["recall_days"])) return null;
|
|
@@ -34785,7 +34803,12 @@ function parseConfig(v) {
|
|
|
34785
34803
|
return Object.freeze({
|
|
34786
34804
|
persona_sha256: v.persona_sha256,
|
|
34787
34805
|
...isPlainObject(v.llm) ? { llm: Object.freeze({ provider: v.llm.provider, model: v.llm.model }) } : {},
|
|
34788
|
-
...isPlainObject(v.search) ? {
|
|
34806
|
+
...isPlainObject(v.search) ? {
|
|
34807
|
+
search: Object.freeze({
|
|
34808
|
+
provider: v.search.provider,
|
|
34809
|
+
..."owner_dm_daily_cap" in v.search ? { owner_dm_daily_cap: v.search.owner_dm_daily_cap } : {}
|
|
34810
|
+
})
|
|
34811
|
+
} : {},
|
|
34789
34812
|
...isStringArray(v.tools_allow) ? { tools_allow: Object.freeze([...v.tools_allow]) } : {},
|
|
34790
34813
|
flags: Object.freeze([...v.flags]),
|
|
34791
34814
|
memory: Object.freeze({ mode: mem.mode, ..."recall_days" in mem ? { recall_days: mem.recall_days } : {} }),
|
|
@@ -35016,7 +35039,20 @@ function bindTargets(raw, signed, equals) {
|
|
|
35016
35039
|
}
|
|
35017
35040
|
return { written, mismatches };
|
|
35018
35041
|
}
|
|
35019
|
-
function
|
|
35042
|
+
function signedManifestTools(manifest, audience, searchProvidersCapable) {
|
|
35043
|
+
return MANIFEST_KNOWN_TOOLS[audience].filter((t) => (manifest.grants[audience] ?? []).includes(t) && (t !== "web_extract" || searchProvidersCapable));
|
|
35044
|
+
}
|
|
35045
|
+
function manifestPolicyFor(manifest, switches, searchProvidersCapable) {
|
|
35046
|
+
return {
|
|
35047
|
+
v: 1,
|
|
35048
|
+
manifest_tools: [.../* @__PURE__ */ new Set([
|
|
35049
|
+
...switches.ownerDm ? signedManifestTools(manifest, "owner_dm", searchProvidersCapable) : [],
|
|
35050
|
+
...switches.room ? signedManifestTools(manifest, "team_room", searchProvidersCapable) : []
|
|
35051
|
+
])].sort(),
|
|
35052
|
+
secret_path_mode: "enforce"
|
|
35053
|
+
};
|
|
35054
|
+
}
|
|
35055
|
+
function bindRuntimeConfig(manifest, payload, prior, switches = { ownerDm: true, room: true }, searchProvidersCapable = false) {
|
|
35020
35056
|
const mismatches = /* @__PURE__ */ new Set();
|
|
35021
35057
|
const cfg = manifest.config;
|
|
35022
35058
|
const out = {};
|
|
@@ -35045,6 +35081,7 @@ function bindRuntimeConfig(manifest, payload, prior, switches = { ownerDm: true,
|
|
|
35045
35081
|
for (const name of Object.keys(files)) {
|
|
35046
35082
|
if (name !== LLM_SOURCE && !PERSONA_FILES.includes(name)) mismatches.add("files");
|
|
35047
35083
|
}
|
|
35084
|
+
const ownerDmTools = signedManifestTools(manifest, "owner_dm", searchProvidersCapable);
|
|
35048
35085
|
const sj = isObj2(payload.skills_json) ? payload.skills_json : void 0;
|
|
35049
35086
|
const eps = bindTargets(sj?.endpoints, manifest.endpoints, endpointEquals);
|
|
35050
35087
|
const dbs = bindTargets(sj?.databases, manifest.databases, databaseEquals);
|
|
@@ -35062,14 +35099,20 @@ function bindRuntimeConfig(manifest, payload, prior, switches = { ownerDm: true,
|
|
|
35062
35099
|
appliedSearch = searchBlock;
|
|
35063
35100
|
} else {
|
|
35064
35101
|
mismatches.add("search");
|
|
35065
|
-
|
|
35102
|
+
const usablePrior = cfg.search !== void 0 && prior.search?.provider === cfg.search.provider ? prior.search : void 0;
|
|
35103
|
+
searchBlock = cfg.search === void 0 ? void 0 : usablePrior ?? Object.freeze({ provider: cfg.search.provider });
|
|
35066
35104
|
}
|
|
35067
35105
|
const skillsDoc = {
|
|
35068
35106
|
endpoints: eps.written,
|
|
35069
35107
|
databases: dbs.written,
|
|
35070
35108
|
flags: [...cfg.flags],
|
|
35071
35109
|
...deny !== void 0 || cfg.tools_allow !== void 0 ? { tools: { ...deny !== void 0 ? { deny } : {}, ...cfg.tools_allow !== void 0 ? { allow: [...cfg.tools_allow] } : {} } } : {},
|
|
35072
|
-
...searchBlock ? { search: searchBlock } : {}
|
|
35110
|
+
...searchBlock ? { search: searchBlock } : {},
|
|
35111
|
+
// D31: the marker the runtime keys D24 (iii) on; written under every manifest, true when config.search is signed.
|
|
35112
|
+
search_signed: cfg.search !== void 0,
|
|
35113
|
+
// D36, D39: the signed owner-DM cap, only when the owner-DM switch is on and the manifest grants an owner-DM tool;
|
|
35114
|
+
// otherwise none, so the runtime clamps a signed raise to the default. Never read from the payload.
|
|
35115
|
+
...cfg.search?.owner_dm_daily_cap !== void 0 && switches.ownerDm && ownerDmTools.length > 0 ? { owner_dm_search_cap: cfg.search.owner_dm_daily_cap } : {}
|
|
35073
35116
|
};
|
|
35074
35117
|
out["skills.json"] = JSON.stringify(skillsDoc, null, 2) + "\n";
|
|
35075
35118
|
const signedMemory = { mode: cfg.memory.mode, ...cfg.memory.recall_days !== void 0 ? { recall_days: cfg.memory.recall_days } : {} };
|
|
@@ -35100,12 +35143,7 @@ function bindRuntimeConfig(manifest, payload, prior, switches = { ownerDm: true,
|
|
|
35100
35143
|
mismatches.add("legacy_assign");
|
|
35101
35144
|
legacyDecisions = decisions.filter((d) => isObj2(d) && d.action === "delete");
|
|
35102
35145
|
}
|
|
35103
|
-
const
|
|
35104
|
-
const policy = {
|
|
35105
|
-
v: 1,
|
|
35106
|
-
manifest_tools: [.../* @__PURE__ */ new Set([...switches.ownerDm ? signedTools("owner_dm") : [], ...switches.room ? signedTools("team_room") : []])].sort(),
|
|
35107
|
-
secret_path_mode: "enforce"
|
|
35108
|
-
};
|
|
35146
|
+
const policy = manifestPolicyFor(manifest, switches, searchProvidersCapable);
|
|
35109
35147
|
return {
|
|
35110
35148
|
mismatches: CONFIG_BINDING_FIELDS.filter((f) => mismatches.has(f)).sort(),
|
|
35111
35149
|
targetMismatches: { endpoint: eps.mismatches, database: dbs.mismatches },
|
|
@@ -35244,6 +35282,8 @@ var TOOL_ROOM_CLASSES = Object.freeze({
|
|
|
35244
35282
|
current_time: Object.freeze(["room_safe_read"]),
|
|
35245
35283
|
echo: Object.freeze(["room_safe_read"]),
|
|
35246
35284
|
web_search: Object.freeze(["owner_credential"]),
|
|
35285
|
+
web_extract: Object.freeze(["owner_credential", "egress"]),
|
|
35286
|
+
// D5: spends the owner's key and sends URLs out
|
|
35247
35287
|
fetch_url: Object.freeze(["egress"]),
|
|
35248
35288
|
sql_query: Object.freeze(["owner_credential"]),
|
|
35249
35289
|
http_request: Object.freeze(["owner_credential", "egress", "side_effect"])
|
|
@@ -35665,6 +35705,8 @@ function hexToBytes4(h) {
|
|
|
35665
35705
|
return new Uint8Array(Buffer.from(h, "hex"));
|
|
35666
35706
|
}
|
|
35667
35707
|
var BOOT_DRAIN_WAIT_MS_DEFAULT = 6e4;
|
|
35708
|
+
var SEARCH_CAPABILITY_REFETCH_DEBOUNCE_MS = 1e3;
|
|
35709
|
+
var SEARCH_CAPABILITY_REFETCH_MAX_WAIT_MS = 1e4;
|
|
35668
35710
|
var BootDrainRotationRefusedError = class extends Error {
|
|
35669
35711
|
constructor() {
|
|
35670
35712
|
super("key-package rotation refused: the boot drain has not settled");
|
|
@@ -35860,6 +35902,8 @@ var BridgeAgent = class _BridgeAgent {
|
|
|
35860
35902
|
this.actionClock = deps.actionThrottleNow ?? Date.now;
|
|
35861
35903
|
this.rng = deps.rng ?? Math.random;
|
|
35862
35904
|
this.bootDrainWaitMs = deps.bootDrainWaitMs ?? BOOT_DRAIN_WAIT_MS_DEFAULT;
|
|
35905
|
+
this.searchCapabilityRefetchDebounceMs = deps.searchCapabilityRefetchDebounceMs ?? SEARCH_CAPABILITY_REFETCH_DEBOUNCE_MS;
|
|
35906
|
+
this.searchCapabilityRefetchMaxWaitMs = deps.searchCapabilityRefetchMaxWaitMs ?? SEARCH_CAPABILITY_REFETCH_MAX_WAIT_MS;
|
|
35863
35907
|
this.replySleep = deps.replySleep ?? ((ms) => new Promise((resolve4) => {
|
|
35864
35908
|
const t = setTimeout(resolve4, ms);
|
|
35865
35909
|
t.unref?.();
|
|
@@ -36298,6 +36342,8 @@ var BridgeAgent = class _BridgeAgent {
|
|
|
36298
36342
|
bootSweepTimer;
|
|
36299
36343
|
rng;
|
|
36300
36344
|
bootDrainWaitMs;
|
|
36345
|
+
searchCapabilityRefetchDebounceMs;
|
|
36346
|
+
searchCapabilityRefetchMaxWaitMs;
|
|
36301
36347
|
/** Resolved (and cleared) each time an ingest cycle settles: see start(). */
|
|
36302
36348
|
ingestSettledWaiters = [];
|
|
36303
36349
|
/** The boot key-package publish, when start() had to defer it. Test seam. */
|
|
@@ -36743,9 +36789,14 @@ var BridgeAgent = class _BridgeAgent {
|
|
|
36743
36789
|
}
|
|
36744
36790
|
const skillsJson = payload.skills_json ?? {};
|
|
36745
36791
|
if (version && inForce === null) {
|
|
36792
|
+
let asDelivered = skillsJson;
|
|
36793
|
+
if (skillsJson !== null && typeof skillsJson === "object" && !Array.isArray(skillsJson)) {
|
|
36794
|
+
const { owner_dm_search_cap: _cap, search_signed: _signed, ...rest } = skillsJson;
|
|
36795
|
+
asDelivered = rest;
|
|
36796
|
+
}
|
|
36746
36797
|
this.grantWriters.writeManagedFiles(this.home, this.cfg.identityId, {
|
|
36747
36798
|
...payload.files ?? {},
|
|
36748
|
-
"skills.json": `${JSON.stringify(
|
|
36799
|
+
"skills.json": `${JSON.stringify(asDelivered, null, 2)}
|
|
36749
36800
|
`
|
|
36750
36801
|
});
|
|
36751
36802
|
}
|
|
@@ -36800,7 +36851,7 @@ var BridgeAgent = class _BridgeAgent {
|
|
|
36800
36851
|
}
|
|
36801
36852
|
let bound;
|
|
36802
36853
|
try {
|
|
36803
|
-
bound = this.grantWriters.bindRuntimeConfig(manifest, payload, { search: prior }, { ownerDm: this.ownerDmManifestGrants, room: this.roomManifestGrants });
|
|
36854
|
+
bound = this.grantWriters.bindRuntimeConfig(manifest, payload, { search: prior }, { ownerDm: this.ownerDmManifestGrants, room: this.roomManifestGrants }, this.searchProvidersCapable());
|
|
36804
36855
|
} catch (e) {
|
|
36805
36856
|
bound = null;
|
|
36806
36857
|
return this.bindFailed(manifest, payload.memory, e);
|
|
@@ -36819,9 +36870,9 @@ var BridgeAgent = class _BridgeAgent {
|
|
|
36819
36870
|
return true;
|
|
36820
36871
|
}
|
|
36821
36872
|
try {
|
|
36822
|
-
this.grantWriters.writeManifestPolicy(this.home, this.cfg.identityId, bound.policy);
|
|
36823
36873
|
this.grantWriters.writeManagedFiles(this.home, this.cfg.identityId, bound.files);
|
|
36824
36874
|
if (manifest.config.llm === void 0) this.grantWriters.removeManagedLlmSource(this.home, this.cfg.identityId);
|
|
36875
|
+
this.grantWriters.writeManifestPolicy(this.home, this.cfg.identityId, manifestPolicyFor(manifest, { ownerDm: this.ownerDmManifestGrants, room: this.roomManifestGrants }, this.searchProvidersCapable()));
|
|
36825
36876
|
} catch (e) {
|
|
36826
36877
|
this.manifestBinding = null;
|
|
36827
36878
|
throw e;
|
|
@@ -36874,6 +36925,7 @@ var BridgeAgent = class _BridgeAgent {
|
|
|
36874
36925
|
/** The report half of refetchRuntimeConfigOnce (split out for the plan 4 Task 11 bind_failed path). */
|
|
36875
36926
|
async postRuntimeConfigReport(base, version, skillsJson) {
|
|
36876
36927
|
const local = readLocalReport(this.home, this.cfg.identityId);
|
|
36928
|
+
const reportedSearchProviders = this.searchProvidersCapable();
|
|
36877
36929
|
const report = {
|
|
36878
36930
|
applied_version: version,
|
|
36879
36931
|
paths: checkConfiguredPaths(skillsJson),
|
|
@@ -36888,6 +36940,13 @@ var BridgeAgent = class _BridgeAgent {
|
|
|
36888
36940
|
// to the backend. The backend needs it to generate a truthful tool
|
|
36889
36941
|
// paragraph, so it rides along here.
|
|
36890
36942
|
has_search_key: local?.has_search_key ?? false,
|
|
36943
|
+
// L-2 (spec §7.9): only the runtime knows whether an extract-capable provider key is readable; never derived
|
|
36944
|
+
// from has_search_key. An older runtime omits it: false.
|
|
36945
|
+
// Final review I-2 (controller ruling): AND the current search_providers_v2, so the web never shows extract while
|
|
36946
|
+
// the bridge withholds web_extract from the runtime.
|
|
36947
|
+
has_extract_provider: (local?.has_extract_provider ?? false) && reportedSearchProviders,
|
|
36948
|
+
// D39: the owner-DM daily cap the runtime enforces, passed through when it reported a valid one; never the signed value.
|
|
36949
|
+
...local?.owner_dm_search_cap_effective !== void 0 ? { owner_dm_search_cap_effective: local.owner_dm_search_cap_effective } : {},
|
|
36891
36950
|
// Same idea, for the BYOK LLM key file: only the runtime can see
|
|
36892
36951
|
// whether one is configured in its own environment.
|
|
36893
36952
|
has_llm_key: local?.has_llm_key ?? false,
|
|
@@ -36927,7 +36986,11 @@ var BridgeAgent = class _BridgeAgent {
|
|
|
36927
36986
|
// Plan 4 Task 15 (OQ-5): sorted, unique enums; capability is the latest hello's class.
|
|
36928
36987
|
config_binding_mismatches: [...this.configBindingMismatches],
|
|
36929
36988
|
target_mismatches: ["database", "endpoint"].filter((k) => this.targetMismatches[k] > 0),
|
|
36930
|
-
capability: this.lastConsumerCapability
|
|
36989
|
+
capability: this.lastConsumerCapability,
|
|
36990
|
+
// D28 (§11.1 step 3): a separate key, never a value in the capability enum. False with no runtime attached.
|
|
36991
|
+
search_providers_v2: reportedSearchProviders,
|
|
36992
|
+
// D19 item 4: content-free; the signed provider is one the attached runtime(s) cannot honour.
|
|
36993
|
+
search_provider_unsupported: this.searchProviderUnsupported(reportedSearchProviders)
|
|
36931
36994
|
}
|
|
36932
36995
|
};
|
|
36933
36996
|
const reportedVerifyFailures = this.ownerVerifyFailures;
|
|
@@ -36948,6 +37011,7 @@ var BridgeAgent = class _BridgeAgent {
|
|
|
36948
37011
|
return;
|
|
36949
37012
|
}
|
|
36950
37013
|
this.ownerVerifyFailures = Math.max(0, this.ownerVerifyFailures - reportedVerifyFailures);
|
|
37014
|
+
this.lastReportedSearchProviders = reportedSearchProviders;
|
|
36951
37015
|
if (version) writeServiceLog("info", "runtime_config.applied", { version });
|
|
36952
37016
|
else writeServiceLog("info", "runtime_config.legacy_memory_reported");
|
|
36953
37017
|
}
|
|
@@ -37017,6 +37081,7 @@ var BridgeAgent = class _BridgeAgent {
|
|
|
37017
37081
|
this.startedAt = Date.now();
|
|
37018
37082
|
await this.restoreRuntimeInbox();
|
|
37019
37083
|
await this.loadToolGrantState();
|
|
37084
|
+
this.recomputeManifestPolicy(false);
|
|
37020
37085
|
try {
|
|
37021
37086
|
this.store.pruneRoomSearchCap(utcDayOf(Date.now()));
|
|
37022
37087
|
} catch (e) {
|
|
@@ -42808,6 +42873,115 @@ ${channelId}`;
|
|
|
42808
42873
|
manifestConsumerAttached() {
|
|
42809
42874
|
return this.manifestConsumer !== null;
|
|
42810
42875
|
}
|
|
42876
|
+
/**
|
|
42877
|
+
* D28 (B-4): every socket that said hello, with whether its latest hello declared search_providers_v2 on the
|
|
42878
|
+
* manifest_grants_v1 predicate (ws-server.ts). The agent value is the AND over all of them, absent (false) with
|
|
42879
|
+
* none: unlike manifestConsumer, never newest wins. The per-delivery filter judges each socket by its own hello.
|
|
42880
|
+
*/
|
|
42881
|
+
searchProvidersSockets = /* @__PURE__ */ new Map();
|
|
42882
|
+
/**
|
|
42883
|
+
* The D28 value the files were last recomputed for; null until the first socket observation, so that observation
|
|
42884
|
+
* always recomputes (final review I-1), even when it is non-capable.
|
|
42885
|
+
*/
|
|
42886
|
+
searchProvidersState = null;
|
|
42887
|
+
searchCapabilityRefetchTimer = null;
|
|
42888
|
+
/** When the current burst's first change happened (valid while the timer is set). */
|
|
42889
|
+
searchCapabilityBurstStart = 0;
|
|
42890
|
+
/** The D28 value in the last report posted (null until one is); a change needs a refetch to reach the web. */
|
|
42891
|
+
lastReportedSearchProviders = null;
|
|
42892
|
+
noteSearchProvidersSocket(token, declared) {
|
|
42893
|
+
this.searchProvidersSockets.set(token, declared);
|
|
42894
|
+
this.onSearchProvidersMaybeChanged();
|
|
42895
|
+
}
|
|
42896
|
+
clearSearchProvidersSocket(token) {
|
|
42897
|
+
if (this.searchProvidersSockets.delete(token)) this.onSearchProvidersMaybeChanged();
|
|
42898
|
+
}
|
|
42899
|
+
/** D28: every attached runtime socket declared search_providers_v2; no socket attached means absent (false). */
|
|
42900
|
+
searchProvidersCapable() {
|
|
42901
|
+
if (this.searchProvidersSockets.size === 0) return false;
|
|
42902
|
+
for (const v of this.searchProvidersSockets.values()) if (!v) return false;
|
|
42903
|
+
return true;
|
|
42904
|
+
}
|
|
42905
|
+
/**
|
|
42906
|
+
* D19 item 3 (B-6): the search provider signed in the stored verified manifest in force (a pin loaded and a good
|
|
42907
|
+
* manifest), never the server payload; undefined with no pin, no manifest, or no signed search block. The
|
|
42908
|
+
* per-delivery filter (consumer-grants.ts withSearchCapability) and the S-28 report reason both read this.
|
|
42909
|
+
*/
|
|
42910
|
+
signedSearchProvider() {
|
|
42911
|
+
const pin = this.cfg.ownerGrantPin?.pin ?? null;
|
|
42912
|
+
return pin !== null ? this.toolGrantManifest?.config.search?.provider : void 0;
|
|
42913
|
+
}
|
|
42914
|
+
/** D19 item 4, D34: the in-force signed provider is not brave, and the attached runtime(s) lack the capability. */
|
|
42915
|
+
searchProviderUnsupported(capable) {
|
|
42916
|
+
if (capable) return false;
|
|
42917
|
+
const provider = this.signedSearchProvider();
|
|
42918
|
+
return provider !== void 0 && provider !== "brave";
|
|
42919
|
+
}
|
|
42920
|
+
/**
|
|
42921
|
+
* D35 (P-4): on a capability change, rewrite manifest-policy.json at once from the stored manifest, the kill
|
|
42922
|
+
* switches and the new capability, then a debounced refetch (one per burst) only when needed.
|
|
42923
|
+
*/
|
|
42924
|
+
onSearchProvidersMaybeChanged() {
|
|
42925
|
+
const capable = this.searchProvidersCapable();
|
|
42926
|
+
const prev = this.searchProvidersState;
|
|
42927
|
+
if (capable === prev) return;
|
|
42928
|
+
this.searchProvidersState = capable;
|
|
42929
|
+
this.recomputeManifestPolicy(capable);
|
|
42930
|
+
if (this.closingDown) return;
|
|
42931
|
+
if (prev === null && !capable) return;
|
|
42932
|
+
const now = Date.now();
|
|
42933
|
+
if (this.searchCapabilityRefetchTimer !== null) clearTimeout(this.searchCapabilityRefetchTimer);
|
|
42934
|
+
else this.searchCapabilityBurstStart = now;
|
|
42935
|
+
const delay = Math.max(0, Math.min(this.searchCapabilityRefetchDebounceMs, this.searchCapabilityBurstStart + this.searchCapabilityRefetchMaxWaitMs - now));
|
|
42936
|
+
this.searchCapabilityRefetchTimer = setTimeout(() => {
|
|
42937
|
+
this.searchCapabilityRefetchTimer = null;
|
|
42938
|
+
if (this.searchCapabilityRefetchNeeded()) void this.refetchRuntimeConfig();
|
|
42939
|
+
}, delay);
|
|
42940
|
+
this.searchCapabilityRefetchTimer.unref?.();
|
|
42941
|
+
}
|
|
42942
|
+
/**
|
|
42943
|
+
* A refetch re-renders skills.json (owner_dm_search_cap counts web_extract only with the capability, D39) and posts
|
|
42944
|
+
* the report. Needed under a manifest in force, or when the reported value is stale. Never before the boot fetch.
|
|
42945
|
+
*/
|
|
42946
|
+
searchCapabilityRefetchNeeded() {
|
|
42947
|
+
if (!this.bootConfigSettled || this.closingDown) return false;
|
|
42948
|
+
const inForce = (this.cfg.ownerGrantPin?.pin ?? null) !== null && this.toolGrantManifest !== null;
|
|
42949
|
+
return inForce || this.lastReportedSearchProviders !== this.searchProvidersCapable();
|
|
42950
|
+
}
|
|
42951
|
+
/**
|
|
42952
|
+
* D35: the local recompute. Widening (web_extract back in) only while the binding for the in-force manifest stands,
|
|
42953
|
+
* so a policy is never written ahead of its skills.json. Narrowing never waits: with no binding in force, a file that
|
|
42954
|
+
* lists web_extract loses it at once, so an older runtime never reads it as unreadable (which drops every grant).
|
|
42955
|
+
* Content-free; a write failure is logged and the debounced refetch tries again.
|
|
42956
|
+
*/
|
|
42957
|
+
recomputeManifestPolicy(capable) {
|
|
42958
|
+
const pin = this.cfg.ownerGrantPin?.pin ?? null;
|
|
42959
|
+
const manifest = pin !== null ? this.toolGrantManifest : null;
|
|
42960
|
+
try {
|
|
42961
|
+
if (manifest !== null && this.manifestBinding !== null && this.manifestBinding.counter === manifest.counter) {
|
|
42962
|
+
this.grantWriters.writeManifestPolicy(this.home, this.cfg.identityId, manifestPolicyFor(manifest, { ownerDm: this.ownerDmManifestGrants, room: this.roomManifestGrants }, capable));
|
|
42963
|
+
return;
|
|
42964
|
+
}
|
|
42965
|
+
if (capable) return;
|
|
42966
|
+
const path = join19(runtimeConfigDir(this.home, this.cfg.identityId), MANIFEST_POLICY_FILE);
|
|
42967
|
+
if (!existsSync5(path)) return;
|
|
42968
|
+
let doc;
|
|
42969
|
+
try {
|
|
42970
|
+
doc = JSON.parse(readFileSync11(path, "utf8"));
|
|
42971
|
+
} catch {
|
|
42972
|
+
return;
|
|
42973
|
+
}
|
|
42974
|
+
const tools = doc?.manifest_tools;
|
|
42975
|
+
if (!Array.isArray(tools) || !tools.includes("web_extract")) return;
|
|
42976
|
+
this.grantWriters.writeManifestPolicy(this.home, this.cfg.identityId, {
|
|
42977
|
+
v: 1,
|
|
42978
|
+
manifest_tools: tools.filter((t) => typeof t === "string" && t !== "web_extract"),
|
|
42979
|
+
secret_path_mode: "enforce"
|
|
42980
|
+
});
|
|
42981
|
+
} catch (e) {
|
|
42982
|
+
writeServiceLog("warn", "authz.search_capability", { state: ServiceLogEnum.of("policy_write_failed", ["policy_write_failed"]) }, e);
|
|
42983
|
+
}
|
|
42984
|
+
}
|
|
42811
42985
|
noteConsumerCapability(state) {
|
|
42812
42986
|
this.lastConsumerCapability = state;
|
|
42813
42987
|
if (state !== "ok") {
|
|
@@ -42999,6 +43173,8 @@ ${channelId}`;
|
|
|
42999
43173
|
this.supersedeRecheckTimers.clear();
|
|
43000
43174
|
if (this.redeliveryTimer !== null) clearTimeout(this.redeliveryTimer);
|
|
43001
43175
|
this.redeliveryTimer = null;
|
|
43176
|
+
if (this.searchCapabilityRefetchTimer !== null) clearTimeout(this.searchCapabilityRefetchTimer);
|
|
43177
|
+
this.searchCapabilityRefetchTimer = null;
|
|
43002
43178
|
this.pingHandle?.close();
|
|
43003
43179
|
if (this.safetyTimer) clearInterval(this.safetyTimer);
|
|
43004
43180
|
if (this.runtimeConfigTimer) clearInterval(this.runtimeConfigTimer);
|
|
@@ -43109,11 +43285,11 @@ ${channelId}`;
|
|
|
43109
43285
|
|
|
43110
43286
|
// src/auth.ts
|
|
43111
43287
|
import { randomBytes as randomBytes11, timingSafeEqual as timingSafeEqual2 } from "node:crypto";
|
|
43112
|
-
import { existsSync as existsSync6, readFileSync as
|
|
43288
|
+
import { existsSync as existsSync6, readFileSync as readFileSync12, writeFileSync as writeFileSync2 } from "node:fs";
|
|
43113
43289
|
function resolveToken(opts) {
|
|
43114
43290
|
if (opts.token) return opts.token;
|
|
43115
43291
|
const f = opts.tokenFile;
|
|
43116
|
-
if (f && existsSync6(f)) return
|
|
43292
|
+
if (f && existsSync6(f)) return readFileSync12(f, "utf8").trim();
|
|
43117
43293
|
const tok = randomBytes11(32).toString("base64url");
|
|
43118
43294
|
if (f) writeFileSync2(f, tok, { mode: 384 });
|
|
43119
43295
|
return tok;
|
|
@@ -43214,6 +43390,7 @@ function withConsumerGrants(m, perToolConsumer) {
|
|
|
43214
43390
|
return { ...m, authorization: Object.freeze({ ...rest, ...stripGrants ? { tool_grants: NO_GRANTS } : {} }) };
|
|
43215
43391
|
}
|
|
43216
43392
|
var MANIFEST_GRANTS_FEATURE = "manifest_grants_v1";
|
|
43393
|
+
var SEARCH_PROVIDERS_FEATURE = "search_providers_v2";
|
|
43217
43394
|
var CONSTANT_TOOL_NAMES = Object.freeze({
|
|
43218
43395
|
owner_dm: Object.freeze(["current_time", "web_search"]),
|
|
43219
43396
|
team_room: Object.freeze(["current_time"])
|
|
@@ -43236,6 +43413,15 @@ function withHarnessGrants(m, withheld) {
|
|
|
43236
43413
|
if (!a || a.tool_grants.length === 0) return m;
|
|
43237
43414
|
return { ...m, authorization: Object.freeze({ ...a, tool_grants: NO_GRANTS }) };
|
|
43238
43415
|
}
|
|
43416
|
+
function withSearchCapability(m, consumerHasFeature, signedProvider) {
|
|
43417
|
+
if (consumerHasFeature) return m;
|
|
43418
|
+
const a = m.authorization;
|
|
43419
|
+
if (!a) return m;
|
|
43420
|
+
const stripSearch = signedProvider !== void 0 && signedProvider !== "brave";
|
|
43421
|
+
const kept = a.tool_grants.filter((g) => g.tool !== "web_extract" && !(stripSearch && g.tool === "web_search"));
|
|
43422
|
+
if (kept.length === a.tool_grants.length) return m;
|
|
43423
|
+
return { ...m, authorization: Object.freeze({ ...a, tool_grants: kept.length === 0 ? NO_GRANTS : Object.freeze(kept) }) };
|
|
43424
|
+
}
|
|
43239
43425
|
|
|
43240
43426
|
// src/http-server.ts
|
|
43241
43427
|
function writeSse(res, msgs, onWriteError) {
|
|
@@ -43258,7 +43444,8 @@ data: ${JSON.stringify(msgs[i])}
|
|
|
43258
43444
|
}
|
|
43259
43445
|
function deliverSseBatch(res, batch, agent, onWriteError) {
|
|
43260
43446
|
const withheld = agent.harnessGrantsWithheld();
|
|
43261
|
-
const
|
|
43447
|
+
const provider = agent.signedSearchProvider();
|
|
43448
|
+
const left3 = writeSse(res, batch.map((m) => withSearchCapability(withManifestCapability(withHarnessGrants(withConsumerGrants(m, false), withheld), false), false, provider)), onWriteError);
|
|
43262
43449
|
const leftIds = new Set(left3.map((message) => message.message_id));
|
|
43263
43450
|
agent.ackRuntimeMessages(batch.filter((message) => !leftIds.has(message.message_id)).map((message) => message.message_id));
|
|
43264
43451
|
if (left3.length) agent.requeueFront(batch.filter((message) => leftIds.has(message.message_id)));
|
|
@@ -43529,7 +43716,10 @@ function createHttpServer(agent, opts) {
|
|
|
43529
43716
|
if (method === "GET" && path === "/v1/messages") {
|
|
43530
43717
|
const channel = url.searchParams.get("channel_id") ?? void 0;
|
|
43531
43718
|
const wait = Math.max(0, Math.min(50, Number(url.searchParams.get("wait") ?? 0)));
|
|
43532
|
-
|
|
43719
|
+
const drained = await agent.drain(channel, wait);
|
|
43720
|
+
const withheld = agent.harnessGrantsWithheld();
|
|
43721
|
+
const provider = agent.signedSearchProvider();
|
|
43722
|
+
return json(res, 200, drained.map((m) => withSearchCapability(withManifestCapability(withHarnessGrants(withConsumerGrants(m, false), withheld), false), false, provider)));
|
|
43533
43723
|
}
|
|
43534
43724
|
if (method === "GET" && path === "/v1/events") {
|
|
43535
43725
|
const channel = url.searchParams.get("channel_id") ?? void 0;
|
|
@@ -43703,6 +43893,7 @@ function attachAgentWebSocket(server, agent, opts) {
|
|
|
43703
43893
|
consumer: "unknown",
|
|
43704
43894
|
perToolGrants: false,
|
|
43705
43895
|
manifestGrants: false,
|
|
43896
|
+
searchProviders: false,
|
|
43706
43897
|
// helloWaitMs 0 keeps today's synchronous initial flush exactly (the opt-out the existing tests use).
|
|
43707
43898
|
deliveryOpen: helloWaitMs <= 0,
|
|
43708
43899
|
deliveryToken: /* @__PURE__ */ new Map(),
|
|
@@ -43756,9 +43947,13 @@ function attachAgentWebSocket(server, agent, opts) {
|
|
|
43756
43947
|
continue;
|
|
43757
43948
|
}
|
|
43758
43949
|
const out = withConsumerNotes(
|
|
43759
|
-
|
|
43760
|
-
|
|
43761
|
-
|
|
43950
|
+
withSearchCapability(
|
|
43951
|
+
withManifestCapability(
|
|
43952
|
+
withHarnessGrants(withConsumerGrants(batch[i], session.perToolGrants), !session.perToolGrants && agent.harnessGrantsWithheld()),
|
|
43953
|
+
session.manifestGrants
|
|
43954
|
+
),
|
|
43955
|
+
session.searchProviders,
|
|
43956
|
+
agent.signedSearchProvider()
|
|
43762
43957
|
),
|
|
43763
43958
|
batch[i],
|
|
43764
43959
|
session,
|
|
@@ -43794,6 +43989,7 @@ function attachAgentWebSocket(server, agent, opts) {
|
|
|
43794
43989
|
const cleanup = () => {
|
|
43795
43990
|
if (cleaned) return;
|
|
43796
43991
|
cleaned = true;
|
|
43992
|
+
session.closed = true;
|
|
43797
43993
|
if (helloTimer) clearTimeout(helloTimer);
|
|
43798
43994
|
agent.noteSessionClose();
|
|
43799
43995
|
unsubscribe();
|
|
@@ -43814,6 +44010,7 @@ function attachAgentWebSocket(server, agent, opts) {
|
|
|
43814
44010
|
if (session.harness) agent.clearHarnessReport(session.harness);
|
|
43815
44011
|
if (session.perToolGrants) agent.clearPerToolConsumer(session);
|
|
43816
44012
|
if (session.manifestGrants) agent.clearManifestConsumer(session);
|
|
44013
|
+
agent.clearSearchProvidersSocket(session);
|
|
43817
44014
|
};
|
|
43818
44015
|
current = { sock, cleanup, sweepStale };
|
|
43819
44016
|
sock.on("close", cleanup);
|
|
@@ -43889,6 +44086,7 @@ async function handleInbound(sock, agent, data, inflight, flush, session) {
|
|
|
43889
44086
|
return;
|
|
43890
44087
|
}
|
|
43891
44088
|
if (m.type === "hello") {
|
|
44089
|
+
if (session.closed) return;
|
|
43892
44090
|
const report = m.harness === void 0 ? null : parseHarnessReport(m.harness);
|
|
43893
44091
|
if (report) {
|
|
43894
44092
|
session.harness = report;
|
|
@@ -43912,6 +44110,8 @@ async function handleInbound(sock, agent, data, inflight, flush, session) {
|
|
|
43912
44110
|
agent.clearManifestConsumer(session);
|
|
43913
44111
|
}
|
|
43914
44112
|
agent.noteConsumerCapability(manifest ? "ok" : session.harnessClaimed ? "harness_consumer" : "missing");
|
|
44113
|
+
session.searchProviders = session.consumer === "runtime" && session.harnessClaimed !== true && perTool && Array.isArray(m.features) && m.features.includes(SEARCH_PROVIDERS_FEATURE);
|
|
44114
|
+
agent.noteSearchProvidersSocket(session, session.searchProviders);
|
|
43915
44115
|
if (session.consumer === "runtime" && session.harnessClaimed !== true && Array.isArray(m.features) && m.features.includes(MEMORY_NOTES_FEATURE)) {
|
|
43916
44116
|
agent.noteNotesConsumer();
|
|
43917
44117
|
}
|
|
@@ -43919,7 +44119,7 @@ async function handleInbound(sock, agent, data, inflight, flush, session) {
|
|
|
43919
44119
|
if (session.recallConsumer) agent.noteRecallConsumer();
|
|
43920
44120
|
session.unifiedConsumer = agent.unifiedFeatureOn() && session.consumer === "runtime" && session.harnessClaimed !== true && Array.isArray(m.features) && m.features.includes(MEMORY_UNIFIED_FEATURE);
|
|
43921
44121
|
if (session.unifiedConsumer) agent.noteUnifiedConsumer();
|
|
43922
|
-
sendJson(sock, { type: "hello", features: ["nack", MEMORY_NOTES_FEATURE, MEMORY_RECALL_FEATURE, ...agent.unifiedFeatureOn() ? [MEMORY_UNIFIED_FEATURE] : [], MANIFEST_GRANTS_FEATURE] });
|
|
44122
|
+
sendJson(sock, { type: "hello", features: ["nack", MEMORY_NOTES_FEATURE, MEMORY_RECALL_FEATURE, ...agent.unifiedFeatureOn() ? [MEMORY_UNIFIED_FEATURE] : [], MANIFEST_GRANTS_FEATURE, SEARCH_PROVIDERS_FEATURE] });
|
|
43923
44123
|
if (!session.deliveryOpen) {
|
|
43924
44124
|
session.deliveryOpen = true;
|
|
43925
44125
|
flush();
|
|
@@ -44145,7 +44345,7 @@ async function handleInbound(sock, agent, data, inflight, flush, session) {
|
|
|
44145
44345
|
var LOWER_UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
|
|
44146
44346
|
|
|
44147
44347
|
// src/bin.ts
|
|
44148
|
-
import { readFileSync as
|
|
44348
|
+
import { readFileSync as readFileSync17, mkdirSync as mkdirSync8, writeFileSync as writeFileSync5, rmSync as rmSync8, existsSync as existsSync7, realpathSync as realpathSync3, readdirSync as readdirSync4, statSync as statSync8, chmodSync as chmodSync6 } from "node:fs";
|
|
44149
44349
|
import { join as join25, dirname as dirname13, isAbsolute as isAbsolute3, resolve as resolve3 } from "node:path";
|
|
44150
44350
|
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
44151
44351
|
import { homedir as homedir5, userInfo } from "node:os";
|
|
@@ -44358,7 +44558,8 @@ function installService(input, deps) {
|
|
|
44358
44558
|
deps.writeFile(cfg.unitPath, renderSystemdUnit(cfg));
|
|
44359
44559
|
deps.run("systemctl", ["--user", "daemon-reload"]);
|
|
44360
44560
|
deps.run("loginctl", ["enable-linger", deps.user]);
|
|
44361
|
-
requireOk(deps.run("systemctl", ["--user", "enable",
|
|
44561
|
+
requireOk(deps.run("systemctl", ["--user", "enable", cfg.unitName]), "systemctl --user enable");
|
|
44562
|
+
requireOk(deps.run("systemctl", ["--user", "restart", cfg.unitName]), "systemctl --user restart");
|
|
44362
44563
|
return { label: cfg.unitName, filePath: cfg.unitPath, logHint: `journalctl --user -u ${cfg.unitName} -f`, tokenHint: tokenHint(input) };
|
|
44363
44564
|
}
|
|
44364
44565
|
throw new ServiceUnsupportedError(`Service install isn't supported on ${deps.platform} yet. Run the agent in a terminal, or use a process manager.`);
|
|
@@ -45107,7 +45308,7 @@ function renderStatusTable(rows) {
|
|
|
45107
45308
|
import {
|
|
45108
45309
|
chmodSync as chmodSync5,
|
|
45109
45310
|
mkdirSync as mkdirSync6,
|
|
45110
|
-
readFileSync as
|
|
45311
|
+
readFileSync as readFileSync13,
|
|
45111
45312
|
renameSync as renameSync4,
|
|
45112
45313
|
unlinkSync as unlinkSync2,
|
|
45113
45314
|
writeFileSync as writeFileSync3
|
|
@@ -45119,7 +45320,7 @@ var REAL_FS2 = {
|
|
|
45119
45320
|
chmod: (p, mode) => chmodSync5(p, mode),
|
|
45120
45321
|
writeFile: (p, data, mode) => writeFileSync3(p, data, { mode }),
|
|
45121
45322
|
rename: (a, b) => renameSync4(a, b),
|
|
45122
|
-
readFile: (p) =>
|
|
45323
|
+
readFile: (p) => readFileSync13(p, "utf8"),
|
|
45123
45324
|
unlink: (p) => unlinkSync2(p)
|
|
45124
45325
|
};
|
|
45125
45326
|
function securecomsDir(home) {
|
|
@@ -45168,7 +45369,7 @@ function removeConnectionFileIfOwned(home, identityId, instanceId, deps = REAL_F
|
|
|
45168
45369
|
|
|
45169
45370
|
// src/service/instance-lock.ts
|
|
45170
45371
|
import { execFileSync } from "node:child_process";
|
|
45171
|
-
import { closeSync as closeSync4, fsyncSync, mkdirSync as mkdirSync7, openSync as openSync4, readFileSync as
|
|
45372
|
+
import { closeSync as closeSync4, fsyncSync, mkdirSync as mkdirSync7, openSync as openSync4, readFileSync as readFileSync14, statSync as statSync6, unlinkSync as unlinkSync3, utimesSync, writeSync as writeSync2 } from "node:fs";
|
|
45172
45373
|
import { hostname, uptime as uptime2 } from "node:os";
|
|
45173
45374
|
import { dirname as dirname11 } from "node:path";
|
|
45174
45375
|
var LOCK_PARTIAL_WRITE_GRACE_MS = 1e4;
|
|
@@ -45182,7 +45383,7 @@ function errno(error) {
|
|
|
45182
45383
|
}
|
|
45183
45384
|
function readTrimmed(path) {
|
|
45184
45385
|
try {
|
|
45185
|
-
const v =
|
|
45386
|
+
const v = readFileSync14(path, "utf8").trim();
|
|
45186
45387
|
return v === "" ? void 0 : v;
|
|
45187
45388
|
} catch {
|
|
45188
45389
|
return void 0;
|
|
@@ -45297,7 +45498,7 @@ var InstanceLock = class {
|
|
|
45297
45498
|
if (!this.held) return false;
|
|
45298
45499
|
let current;
|
|
45299
45500
|
try {
|
|
45300
|
-
current =
|
|
45501
|
+
current = readFileSync14(this.path, "utf8");
|
|
45301
45502
|
} catch {
|
|
45302
45503
|
current = void 0;
|
|
45303
45504
|
}
|
|
@@ -45315,7 +45516,7 @@ var InstanceLock = class {
|
|
|
45315
45516
|
let ageMs;
|
|
45316
45517
|
this.env.beforeLockRead?.();
|
|
45317
45518
|
try {
|
|
45318
|
-
raw =
|
|
45519
|
+
raw = readFileSync14(this.path, "utf8");
|
|
45319
45520
|
ageMs = Date.now() - statSync6(this.path).mtimeMs;
|
|
45320
45521
|
} catch (error) {
|
|
45321
45522
|
if (errno(error) === "ENOENT") {
|
|
@@ -45356,7 +45557,7 @@ var InstanceLock = class {
|
|
|
45356
45557
|
const written = this.written;
|
|
45357
45558
|
this.drop();
|
|
45358
45559
|
try {
|
|
45359
|
-
if (written !== void 0 &&
|
|
45560
|
+
if (written !== void 0 && readFileSync14(this.path, "utf8") === written) unlinkSync3(this.path);
|
|
45360
45561
|
} catch {
|
|
45361
45562
|
}
|
|
45362
45563
|
}
|
|
@@ -45370,7 +45571,7 @@ var InstanceLock = class {
|
|
|
45370
45571
|
took() {
|
|
45371
45572
|
this.held = true;
|
|
45372
45573
|
try {
|
|
45373
|
-
this.written =
|
|
45574
|
+
this.written = readFileSync14(this.path, "utf8");
|
|
45374
45575
|
} catch {
|
|
45375
45576
|
this.written = void 0;
|
|
45376
45577
|
}
|
|
@@ -45452,7 +45653,7 @@ var InstanceLock = class {
|
|
|
45452
45653
|
this.env.beforeTakeoverReread?.();
|
|
45453
45654
|
let current;
|
|
45454
45655
|
try {
|
|
45455
|
-
current =
|
|
45656
|
+
current = readFileSync14(this.path, "utf8");
|
|
45456
45657
|
} catch {
|
|
45457
45658
|
current = void 0;
|
|
45458
45659
|
}
|
|
@@ -45466,7 +45667,7 @@ var InstanceLock = class {
|
|
|
45466
45667
|
if (created !== "created") {
|
|
45467
45668
|
if (created === "failed") return "failed";
|
|
45468
45669
|
try {
|
|
45469
|
-
this.holderPid = parseBody(
|
|
45670
|
+
this.holderPid = parseBody(readFileSync14(this.path, "utf8"))?.pid;
|
|
45470
45671
|
} catch {
|
|
45471
45672
|
}
|
|
45472
45673
|
return "held";
|
|
@@ -45492,7 +45693,7 @@ import {
|
|
|
45492
45693
|
fsyncSync as fsyncSync2,
|
|
45493
45694
|
lstatSync as lstatSync8,
|
|
45494
45695
|
openSync as openSync5,
|
|
45495
|
-
readFileSync as
|
|
45696
|
+
readFileSync as readFileSync15,
|
|
45496
45697
|
realpathSync as realpathSync2,
|
|
45497
45698
|
renameSync as renameSync5,
|
|
45498
45699
|
unlinkSync as unlinkSync4,
|
|
@@ -45529,7 +45730,7 @@ function isSymlink(path) {
|
|
|
45529
45730
|
}
|
|
45530
45731
|
}
|
|
45531
45732
|
function readJson(path) {
|
|
45532
|
-
return JSON.parse(
|
|
45733
|
+
return JSON.parse(readFileSync15(path, "utf8"));
|
|
45533
45734
|
}
|
|
45534
45735
|
function publicKeyOf(v) {
|
|
45535
45736
|
const r = parsePinObject(v);
|
|
@@ -45773,7 +45974,7 @@ function realResolveDeps() {
|
|
|
45773
45974
|
}
|
|
45774
45975
|
function realPrepDeps() {
|
|
45775
45976
|
return {
|
|
45776
|
-
readFile: (p) =>
|
|
45977
|
+
readFile: (p) => readFileSync17(p, "utf8"),
|
|
45777
45978
|
writeFileMode: (p, data, mode) => writeFileSync5(p, data, { mode }),
|
|
45778
45979
|
mkdirp: (p, mode) => {
|
|
45779
45980
|
mkdirSync8(p, { recursive: true, mode: mode ?? 493 });
|
|
@@ -45826,7 +46027,7 @@ function realReadFleet() {
|
|
|
45826
46027
|
return [];
|
|
45827
46028
|
}
|
|
45828
46029
|
},
|
|
45829
|
-
readFile: (p) =>
|
|
46030
|
+
readFile: (p) => readFileSync17(p, "utf8")
|
|
45830
46031
|
});
|
|
45831
46032
|
}
|
|
45832
46033
|
function runStatus() {
|
|
@@ -45851,7 +46052,7 @@ function realCopyConnector(srcDir, dstDir, harness) {
|
|
|
45851
46052
|
}
|
|
45852
46053
|
if (name.includes(".test.")) continue;
|
|
45853
46054
|
if (!allowedExt.some((ext) => name.endsWith(ext))) continue;
|
|
45854
|
-
writeFileSync5(join25(dstDir, name),
|
|
46055
|
+
writeFileSync5(join25(dstDir, name), readFileSync17(srcPath));
|
|
45855
46056
|
}
|
|
45856
46057
|
}
|
|
45857
46058
|
function realWriteBinding(dstDir, identityId) {
|
|
@@ -45860,7 +46061,7 @@ function realWriteBinding(dstDir, identityId) {
|
|
|
45860
46061
|
}
|
|
45861
46062
|
function realReadBinding(dstDir) {
|
|
45862
46063
|
try {
|
|
45863
|
-
const parsed = JSON.parse(
|
|
46064
|
+
const parsed = JSON.parse(readFileSync17(join25(dstDir, "securecoms.binding.json"), "utf8"));
|
|
45864
46065
|
return parsed.identity_id ?? null;
|
|
45865
46066
|
} catch {
|
|
45866
46067
|
return null;
|
|
@@ -45878,7 +46079,7 @@ function realStatDir(p) {
|
|
|
45878
46079
|
}
|
|
45879
46080
|
function realReadHermesConfig(p) {
|
|
45880
46081
|
try {
|
|
45881
|
-
return
|
|
46082
|
+
return readFileSync17(p, "utf8");
|
|
45882
46083
|
} catch {
|
|
45883
46084
|
return null;
|
|
45884
46085
|
}
|
|
@@ -46268,7 +46469,7 @@ async function runMode(deps) {
|
|
|
46268
46469
|
served = await deps.serve(agent, {
|
|
46269
46470
|
token,
|
|
46270
46471
|
allowOrigins: daemon.allowOrigins,
|
|
46271
|
-
readTls: () => daemon.tls ? { cert:
|
|
46472
|
+
readTls: () => daemon.tls ? { cert: readFileSync17(daemon.tlsCert, "utf8"), key: readFileSync17(daemon.tlsKey, "utf8") } : void 0
|
|
46272
46473
|
});
|
|
46273
46474
|
} catch (e) {
|
|
46274
46475
|
if (!(e instanceof SessionSupersededError)) throw e;
|