@legioncodeinc/honeycomb 0.1.8 → 0.1.9
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/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/bundle/cli.js +496 -74
- package/daemon/dashboard-app.js +23 -23
- package/daemon/index.js +1576 -769
- package/daemon/restart-helper.js +41 -0
- package/embeddings/embed-daemon.js +1 -1
- package/harnesses/claude-code/.claude-plugin/plugin.json +1 -1
- package/harnesses/claude-code/bundle/capture.js +45 -31
- package/harnesses/claude-code/bundle/index.js +45 -31
- package/harnesses/claude-code/bundle/pre-tool-use.js +45 -31
- package/harnesses/claude-code/bundle/session-end.js +45 -31
- package/harnesses/claude-code/bundle/session-start.js +45 -31
- package/harnesses/codex/bundle/capture.js +45 -31
- package/harnesses/codex/bundle/index.js +45 -31
- package/harnesses/codex/bundle/pre-tool-use.js +45 -31
- package/harnesses/codex/bundle/session-start.js +45 -31
- package/harnesses/codex/package.json +1 -1
- package/harnesses/cursor/bundle/capture.js +45 -31
- package/harnesses/cursor/bundle/index.js +45 -31
- package/harnesses/cursor/bundle/pre-tool-use.js +45 -31
- package/harnesses/cursor/bundle/session-end.js +45 -31
- package/harnesses/cursor/bundle/session-start.js +45 -31
- package/harnesses/openclaw/dist/index.js +1 -1
- package/harnesses/openclaw/openclaw.plugin.json +1 -1
- package/harnesses/openclaw/package.json +1 -1
- package/mcp/bundle/server.js +1 -1
- package/package.json +1 -1
package/daemon/index.js
CHANGED
|
@@ -7369,7 +7369,7 @@ var require_dist = __commonJS({
|
|
|
7369
7369
|
// dist/src/shared/constants.js
|
|
7370
7370
|
var DAEMON_PORT = 3850;
|
|
7371
7371
|
var DAEMON_HOST = "127.0.0.1";
|
|
7372
|
-
var HONEYCOMB_VERSION = true ? "0.1.
|
|
7372
|
+
var HONEYCOMB_VERSION = true ? "0.1.9" : "0.0.0-dev";
|
|
7373
7373
|
|
|
7374
7374
|
// node_modules/zod/v4/classic/external.js
|
|
7375
7375
|
var external_exports = {};
|
|
@@ -22440,7 +22440,7 @@ var responseViaResponseObject = async (res, outgoing, options = {}) => {
|
|
|
22440
22440
|
});
|
|
22441
22441
|
if (!chunk) {
|
|
22442
22442
|
if (i === 1) {
|
|
22443
|
-
await new Promise((
|
|
22443
|
+
await new Promise((resolve7) => setTimeout(resolve7));
|
|
22444
22444
|
maxReadCount = 3;
|
|
22445
22445
|
continue;
|
|
22446
22446
|
}
|
|
@@ -22593,7 +22593,7 @@ async function startDaemon(daemon) {
|
|
|
22593
22593
|
let server;
|
|
22594
22594
|
let boundPort = daemon.config.port;
|
|
22595
22595
|
try {
|
|
22596
|
-
server = await new Promise((
|
|
22596
|
+
server = await new Promise((resolve7, reject) => {
|
|
22597
22597
|
let handle;
|
|
22598
22598
|
try {
|
|
22599
22599
|
handle = serve({
|
|
@@ -22602,7 +22602,7 @@ async function startDaemon(daemon) {
|
|
|
22602
22602
|
port: daemon.config.port
|
|
22603
22603
|
}, (info) => {
|
|
22604
22604
|
boundPort = info.port;
|
|
22605
|
-
|
|
22605
|
+
resolve7(handle);
|
|
22606
22606
|
});
|
|
22607
22607
|
handle.on?.("error", (err) => reject(err));
|
|
22608
22608
|
} catch (err) {
|
|
@@ -22617,13 +22617,13 @@ async function startDaemon(daemon) {
|
|
|
22617
22617
|
return {
|
|
22618
22618
|
address: { host: daemon.config.host, port: boundPort },
|
|
22619
22619
|
async close() {
|
|
22620
|
-
await new Promise((
|
|
22620
|
+
await new Promise((resolve7, reject) => {
|
|
22621
22621
|
server.close((err) => {
|
|
22622
22622
|
if (err) {
|
|
22623
22623
|
reject(err instanceof Error ? err : new Error(String(err)));
|
|
22624
22624
|
return;
|
|
22625
22625
|
}
|
|
22626
|
-
|
|
22626
|
+
resolve7();
|
|
22627
22627
|
});
|
|
22628
22628
|
});
|
|
22629
22629
|
await daemon.stopServices();
|
|
@@ -27827,8 +27827,9 @@ function createEmbedSupervisor(deps = {}) {
|
|
|
27827
27827
|
const cfg = resolveConfig2(deps.config);
|
|
27828
27828
|
const spawnChild = deps.spawnChild ?? defaultSpawnChild(env);
|
|
27829
27829
|
const probeHealth = deps.probeHealth ?? defaultProbeHealth(env);
|
|
27830
|
-
|
|
27830
|
+
let enabled = deps.enabled ?? resolveEmbedClientOptions(env).enabled;
|
|
27831
27831
|
let started = false;
|
|
27832
|
+
let lifecycleStarted = false;
|
|
27832
27833
|
let stopping = false;
|
|
27833
27834
|
let child = null;
|
|
27834
27835
|
let live = false;
|
|
@@ -27899,7 +27900,7 @@ function createEmbedSupervisor(deps = {}) {
|
|
|
27899
27900
|
return;
|
|
27900
27901
|
await spawnAndWatch();
|
|
27901
27902
|
}
|
|
27902
|
-
|
|
27903
|
+
const api = {
|
|
27903
27904
|
get live() {
|
|
27904
27905
|
return live;
|
|
27905
27906
|
},
|
|
@@ -27907,16 +27908,17 @@ function createEmbedSupervisor(deps = {}) {
|
|
|
27907
27908
|
return warm;
|
|
27908
27909
|
},
|
|
27909
27910
|
get disabled() {
|
|
27910
|
-
return
|
|
27911
|
+
return !enabled;
|
|
27911
27912
|
},
|
|
27912
27913
|
get restarts() {
|
|
27913
27914
|
return restarts;
|
|
27914
27915
|
},
|
|
27915
27916
|
async start() {
|
|
27917
|
+
lifecycleStarted = true;
|
|
27916
27918
|
if (started)
|
|
27917
27919
|
return;
|
|
27918
27920
|
started = true;
|
|
27919
|
-
if (
|
|
27921
|
+
if (!enabled) {
|
|
27920
27922
|
logger.event("embed.disabled");
|
|
27921
27923
|
return;
|
|
27922
27924
|
}
|
|
@@ -27958,12 +27960,29 @@ function createEmbedSupervisor(deps = {}) {
|
|
|
27958
27960
|
live = false;
|
|
27959
27961
|
warm = false;
|
|
27960
27962
|
restarts = 0;
|
|
27961
|
-
if (
|
|
27963
|
+
if (!enabled || stopping)
|
|
27962
27964
|
return;
|
|
27963
27965
|
logger.event("embed.manual_restart");
|
|
27964
27966
|
await spawnAndWatch();
|
|
27967
|
+
},
|
|
27968
|
+
async setEnabled(want) {
|
|
27969
|
+
enabled = want;
|
|
27970
|
+
if (want) {
|
|
27971
|
+
logger.event("embed.enabled");
|
|
27972
|
+
if (!lifecycleStarted)
|
|
27973
|
+
return;
|
|
27974
|
+
if (child === null) {
|
|
27975
|
+
started = false;
|
|
27976
|
+
await api.start();
|
|
27977
|
+
}
|
|
27978
|
+
} else {
|
|
27979
|
+
logger.event("embed.disabled_live");
|
|
27980
|
+
if (child !== null)
|
|
27981
|
+
await api.stop();
|
|
27982
|
+
}
|
|
27965
27983
|
}
|
|
27966
27984
|
};
|
|
27985
|
+
return api;
|
|
27967
27986
|
}
|
|
27968
27987
|
var noopEmbedSupervisor = {
|
|
27969
27988
|
live: false,
|
|
@@ -27975,6 +27994,8 @@ var noopEmbedSupervisor = {
|
|
|
27975
27994
|
stop() {
|
|
27976
27995
|
},
|
|
27977
27996
|
async restart() {
|
|
27997
|
+
},
|
|
27998
|
+
async setEnabled() {
|
|
27978
27999
|
}
|
|
27979
28000
|
};
|
|
27980
28001
|
|
|
@@ -27983,7 +28004,9 @@ function buildHealthDetail(inputs) {
|
|
|
27983
28004
|
const reasons = {
|
|
27984
28005
|
storage: inputs.status === "ok" ? "reachable" : "unreachable",
|
|
27985
28006
|
embeddings: inputs.embeddingsEnabled ? "on" : "off",
|
|
27986
|
-
schema: inputs.schemaMissingTable === true ? "missing_table" : "ok"
|
|
28007
|
+
schema: inputs.schemaMissingTable === true ? "missing_table" : "ok",
|
|
28008
|
+
// PRD-063b / b-AC-7: read the supplied Portkey state verbatim (no probe). Omitted → `off`.
|
|
28009
|
+
portkey: inputs.portkey ?? "off"
|
|
27987
28010
|
};
|
|
27988
28011
|
return { status: inputs.status, reasons };
|
|
27989
28012
|
}
|
|
@@ -28018,6 +28041,10 @@ var ROUTE_GROUPS = Object.freeze([
|
|
|
28018
28041
|
{ path: "/api/org", protect: true, session: false },
|
|
28019
28042
|
{ path: "/api/workspace", protect: true, session: false },
|
|
28020
28043
|
{ path: "/api/diagnostics", protect: true, session: false },
|
|
28044
|
+
// The dashboard imperative-actions surface (logout / embeddings / restart / uninstall). Protected
|
|
28045
|
+
// (inherits auth/RBAC) AND additionally local-mode + origin/CSRF gated inside the handlers
|
|
28046
|
+
// (`dashboard/actions-api.ts`), since these are credential/process/lifecycle actions.
|
|
28047
|
+
{ path: "/api/actions", protect: true, session: false },
|
|
28021
28048
|
{ path: "/api/pipeline", protect: true, session: false },
|
|
28022
28049
|
{ path: "/api/repair", protect: true, session: false },
|
|
28023
28050
|
{ path: "/api/inference", protect: true, session: false },
|
|
@@ -28155,7 +28182,7 @@ function coarsePipelineStatus(storage) {
|
|
|
28155
28182
|
}
|
|
28156
28183
|
|
|
28157
28184
|
// dist/src/daemon/runtime/assemble.js
|
|
28158
|
-
import { mkdirSync as mkdirSync20, readFileSync as readFileSync22, rmSync as
|
|
28185
|
+
import { mkdirSync as mkdirSync20, mkdtempSync, readFileSync as readFileSync22, rmSync as rmSync10, writeFileSync as writeFileSync17 } from "node:fs";
|
|
28159
28186
|
import { homedir as homedir25 } from "node:os";
|
|
28160
28187
|
import { join as join32 } from "node:path";
|
|
28161
28188
|
|
|
@@ -28583,7 +28610,7 @@ function buildAllowedProperties(input) {
|
|
|
28583
28610
|
}
|
|
28584
28611
|
var systemTelemetryClock = () => (/* @__PURE__ */ new Date()).toISOString();
|
|
28585
28612
|
var DEFAULT_EMIT_TIMEOUT_MS = 2e3;
|
|
28586
|
-
var HONEYCOMB_VERSION2 = true ? "0.1.
|
|
28613
|
+
var HONEYCOMB_VERSION2 = true ? "0.1.9" : "0.0.0-dev";
|
|
28587
28614
|
async function emitTelemetry(event, opts, deps = {}) {
|
|
28588
28615
|
const env = deps.env ?? process.env;
|
|
28589
28616
|
const key = deps.posthogKey ?? POSTHOG_KEY;
|
|
@@ -28653,7 +28680,7 @@ async function postCapture(event, properties, distinctId, key, deps) {
|
|
|
28653
28680
|
}
|
|
28654
28681
|
|
|
28655
28682
|
// dist/src/daemon/runtime/auth/deeplake-issuer.js
|
|
28656
|
-
var realSleeper = (ms) => new Promise((
|
|
28683
|
+
var realSleeper = (ms) => new Promise((resolve7) => setTimeout(resolve7, ms));
|
|
28657
28684
|
var DEEPLAKE_CLIENT_HEADER = "X-Deeplake-Client";
|
|
28658
28685
|
var DEEPLAKE_ORG_HEADER = "X-Activeloop-Org-Id";
|
|
28659
28686
|
var DEEPLAKE_CLIENT_VALUE = "honeycomb";
|
|
@@ -29181,7 +29208,7 @@ function resolveRequestScope(input) {
|
|
|
29181
29208
|
|
|
29182
29209
|
// dist/src/daemon/runtime/auth/device-flow.js
|
|
29183
29210
|
import { timingSafeEqual as timingSafeEqual2 } from "node:crypto";
|
|
29184
|
-
var realSleeper2 = (ms) => new Promise((
|
|
29211
|
+
var realSleeper2 = (ms) => new Promise((resolve7) => setTimeout(resolve7, ms));
|
|
29185
29212
|
var DEFAULT_MAX_POLLS2 = 900;
|
|
29186
29213
|
function reporterOf(deps) {
|
|
29187
29214
|
return deps.reporter ?? { prompt: (line) => console.log(line) };
|
|
@@ -29963,7 +29990,7 @@ function recursEnough(pairs) {
|
|
|
29963
29990
|
}
|
|
29964
29991
|
var systemGateSpawner = {
|
|
29965
29992
|
run(spec, prompt, timeoutMs) {
|
|
29966
|
-
return new Promise((
|
|
29993
|
+
return new Promise((resolve7, reject) => {
|
|
29967
29994
|
const child = spawn2(spec.command, [...spec.args], { shell: false, windowsHide: true });
|
|
29968
29995
|
let stdout = "";
|
|
29969
29996
|
let settled = false;
|
|
@@ -29987,7 +30014,7 @@ var systemGateSpawner = {
|
|
|
29987
30014
|
child.on("error", (err) => finish(() => reject(err)));
|
|
29988
30015
|
child.on("close", (code) => {
|
|
29989
30016
|
if (code === 0)
|
|
29990
|
-
finish(() =>
|
|
30017
|
+
finish(() => resolve7(stdout));
|
|
29991
30018
|
else
|
|
29992
30019
|
finish(() => reject(new Error(`skillify gate CLI exited with code ${code ?? "null"}`)));
|
|
29993
30020
|
});
|
|
@@ -30091,7 +30118,7 @@ function uniqueSessionIds(pairs) {
|
|
|
30091
30118
|
return out;
|
|
30092
30119
|
}
|
|
30093
30120
|
function withTimeout(promise2, timeoutMs, message) {
|
|
30094
|
-
return new Promise((
|
|
30121
|
+
return new Promise((resolve7, reject) => {
|
|
30095
30122
|
let settled = false;
|
|
30096
30123
|
const timer = setTimeout(() => {
|
|
30097
30124
|
if (settled)
|
|
@@ -30104,7 +30131,7 @@ function withTimeout(promise2, timeoutMs, message) {
|
|
|
30104
30131
|
return;
|
|
30105
30132
|
settled = true;
|
|
30106
30133
|
clearTimeout(timer);
|
|
30107
|
-
|
|
30134
|
+
resolve7(v);
|
|
30108
30135
|
}, (e) => {
|
|
30109
30136
|
if (settled)
|
|
30110
30137
|
return;
|
|
@@ -30479,7 +30506,7 @@ function buildSummaryPrompt(session, events) {
|
|
|
30479
30506
|
}
|
|
30480
30507
|
var systemSummarySpawner = {
|
|
30481
30508
|
run(spec, prompt, timeoutMs) {
|
|
30482
|
-
return new Promise((
|
|
30509
|
+
return new Promise((resolve7, reject) => {
|
|
30483
30510
|
const child = spawn3(spec.command, [...spec.args], {
|
|
30484
30511
|
shell: false,
|
|
30485
30512
|
windowsHide: true,
|
|
@@ -30515,7 +30542,7 @@ var systemSummarySpawner = {
|
|
|
30515
30542
|
child.on("error", (err) => finish(() => reject(err)));
|
|
30516
30543
|
child.on("close", (code) => {
|
|
30517
30544
|
if (code === 0)
|
|
30518
|
-
finish(() =>
|
|
30545
|
+
finish(() => resolve7(stdout));
|
|
30519
30546
|
else
|
|
30520
30547
|
finish(() => reject(new Error(`summary gate CLI exited with code ${code ?? "null"}`)));
|
|
30521
30548
|
});
|
|
@@ -30536,7 +30563,7 @@ function createHostSummaryGenCli(spec, spawner = systemSummarySpawner, timeoutMs
|
|
|
30536
30563
|
}
|
|
30537
30564
|
var systemSleeper = {
|
|
30538
30565
|
sleep(ms) {
|
|
30539
|
-
return new Promise((
|
|
30566
|
+
return new Promise((resolve7) => setTimeout(resolve7, ms));
|
|
30540
30567
|
}
|
|
30541
30568
|
};
|
|
30542
30569
|
async function runSummaryWorker(trigger, session, deps) {
|
|
@@ -33779,6 +33806,11 @@ async function runGraphBuild(identity, scope, options) {
|
|
|
33779
33806
|
push: push.kind
|
|
33780
33807
|
};
|
|
33781
33808
|
}
|
|
33809
|
+
async function buildCodebaseGraphSnapshot(scope, options) {
|
|
33810
|
+
const workspaceDir = options.workspaceDir ?? process.cwd();
|
|
33811
|
+
const identity = options.identity ?? resolveSnapshotIdentity(workspaceDir, scope);
|
|
33812
|
+
return runGraphBuild(identity, scope, options);
|
|
33813
|
+
}
|
|
33782
33814
|
function mountGraphApi(daemon, options) {
|
|
33783
33815
|
const group = daemon.group(GRAPH_GROUP);
|
|
33784
33816
|
if (group === void 0)
|
|
@@ -35696,7 +35728,7 @@ function modeledMemoryInjectionSavings(sessions, rate = resolveRate(void 0, void
|
|
|
35696
35728
|
}
|
|
35697
35729
|
|
|
35698
35730
|
// dist/src/daemon/runtime/dashboard/roi-billing.js
|
|
35699
|
-
var realSleeper3 = (ms) => new Promise((
|
|
35731
|
+
var realSleeper3 = (ms) => new Promise((resolve7) => setTimeout(resolve7, ms));
|
|
35700
35732
|
var systemBillingClock = {
|
|
35701
35733
|
now() {
|
|
35702
35734
|
return Date.now();
|
|
@@ -36178,30 +36210,35 @@ async function selectRows2(storage, sql, scope) {
|
|
|
36178
36210
|
return isOk(result) ? result.rows : [];
|
|
36179
36211
|
}
|
|
36180
36212
|
var CHARS_PER_TOKEN2 = 4;
|
|
36181
|
-
async function
|
|
36213
|
+
async function fetchKpiCounts(storage, scope, projectId) {
|
|
36182
36214
|
const memTbl = sqlIdent("memories");
|
|
36183
36215
|
const sessTbl = sqlIdent("sessions");
|
|
36184
|
-
const
|
|
36185
|
-
|
|
36186
|
-
selectRows2(storage, `SELECT COUNT(*) AS n FROM "${
|
|
36187
|
-
selectRows2(storage,
|
|
36216
|
+
const projClause = projectWhereClause(projectId);
|
|
36217
|
+
const [memRows, sessRows, teamSkillRows] = await Promise.all([
|
|
36218
|
+
selectRows2(storage, `SELECT COUNT(*) AS n FROM "${memTbl}"${projClause}`, scope),
|
|
36219
|
+
selectRows2(storage, `SELECT COUNT(*) AS n FROM "${sessTbl}"${projClause}`, scope),
|
|
36188
36220
|
selectRows2(storage, buildTeamSkillCountSql(), scope)
|
|
36189
36221
|
]);
|
|
36190
36222
|
const sessionCount = toNum2(sessRows[0]?.n);
|
|
36191
|
-
const estimatedSavings = Math.floor(toNum2(savingsRows[0]?.chars) / CHARS_PER_TOKEN2);
|
|
36192
36223
|
return {
|
|
36193
36224
|
memoryCount: toNum2(memRows[0]?.n),
|
|
36194
36225
|
// 035a: same value, two names — `sessionCount` kept (additive), `turnCount` is what the UI reads.
|
|
36195
36226
|
sessionCount,
|
|
36196
36227
|
turnCount: sessionCount,
|
|
36197
|
-
estimatedSavings,
|
|
36198
36228
|
teamSkillCount: toNum2(teamSkillRows[0]?.n)
|
|
36199
36229
|
};
|
|
36200
36230
|
}
|
|
36201
|
-
function
|
|
36231
|
+
async function fetchEstimatedSavings(storage, scope, projectId) {
|
|
36232
|
+
const savingsRows = await selectRows2(storage, buildEstimatedSavingsSql(projectId), scope);
|
|
36233
|
+
return Math.floor(toNum2(savingsRows[0]?.chars) / CHARS_PER_TOKEN2);
|
|
36234
|
+
}
|
|
36235
|
+
function buildEstimatedSavingsSql(projectId) {
|
|
36202
36236
|
const tbl = sqlIdent("memories");
|
|
36203
36237
|
const col = sqlIdent("content");
|
|
36204
|
-
return `SELECT SUM(LENGTH(${col})) AS chars FROM "${tbl}"`;
|
|
36238
|
+
return `SELECT SUM(LENGTH(${col})) AS chars FROM "${tbl}"${projectWhereClause(projectId)}`;
|
|
36239
|
+
}
|
|
36240
|
+
function projectWhereClause(projectId) {
|
|
36241
|
+
return projectId !== void 0 && projectId !== "" ? ` WHERE ${sqlIdent("project_id")} = ${sLiteral(projectId)}` : "";
|
|
36205
36242
|
}
|
|
36206
36243
|
function buildTeamSkillCountSql() {
|
|
36207
36244
|
const tbl = sqlIdent(SYNCED_ASSETS_TABLE);
|
|
@@ -36375,7 +36412,7 @@ async function readCapturedTurns(storage, scope, projectId) {
|
|
|
36375
36412
|
const tbl = sqlIdent("sessions");
|
|
36376
36413
|
const dateCol = sqlIdent("creation_date");
|
|
36377
36414
|
const idCol = sqlIdent("id");
|
|
36378
|
-
const projClause =
|
|
36415
|
+
const projClause = projectWhereClause(projectId);
|
|
36379
36416
|
const sql = `SELECT ${sqlIdent("input_tokens")}, ${sqlIdent("output_tokens")}, ${sqlIdent("cache_read_input_tokens")}, ${sqlIdent("cache_creation_input_tokens")}, ${sqlIdent("source_tool")} FROM "${tbl}"${projClause} ORDER BY ${dateCol} DESC, ${idCol} DESC LIMIT ${ROI_SESSIONS_LIMIT}`;
|
|
36380
36417
|
const rows = await selectRows2(storage, sql, scope);
|
|
36381
36418
|
return rows.map(rowToCapturedTurn);
|
|
@@ -36524,22 +36561,34 @@ function mountDashboardApi(daemon, options) {
|
|
|
36524
36561
|
const resolveScope5 = (c) => resolveScopeOrLocalDefault(c, daemon.config.mode, options.defaultScope);
|
|
36525
36562
|
const kpis = daemon.group(DASHBOARD_GROUPS.kpis);
|
|
36526
36563
|
if (kpis !== void 0) {
|
|
36564
|
+
const countsCache = createTtlViewCache(DIAG_TTL_MS);
|
|
36565
|
+
const savingsCache = createTtlViewCache(SAVINGS_TTL_MS);
|
|
36527
36566
|
kpis.get("/kpis", async (c) => {
|
|
36528
36567
|
const scope = resolveScope5(c);
|
|
36529
36568
|
if (scope === null)
|
|
36530
36569
|
return c.json(NO_ORG_BODY4, 400);
|
|
36531
|
-
|
|
36570
|
+
const project = resolveRequestProject(c, scope);
|
|
36571
|
+
const projectId = project.degraded ? void 0 : project.projectId;
|
|
36572
|
+
const key = scopeCacheKey(scope, projectId);
|
|
36573
|
+
const [counts, estimatedSavings] = await Promise.all([
|
|
36574
|
+
countsCache(key, () => fetchKpiCounts(storage, scope, projectId)),
|
|
36575
|
+
savingsCache(key, () => fetchEstimatedSavings(storage, scope, projectId))
|
|
36576
|
+
]);
|
|
36577
|
+
return c.json({ ...counts, estimatedSavings });
|
|
36532
36578
|
});
|
|
36533
36579
|
}
|
|
36534
36580
|
const sessions = daemon.group(DASHBOARD_GROUPS.sessions);
|
|
36535
36581
|
if (sessions !== void 0) {
|
|
36582
|
+
const sessionsCache = createTtlViewCache(DIAG_TTL_MS);
|
|
36536
36583
|
sessions.get("/sessions", async (c) => {
|
|
36537
36584
|
const scope = resolveScope5(c);
|
|
36538
36585
|
if (scope === null)
|
|
36539
36586
|
return c.json(NO_ORG_BODY4, 400);
|
|
36587
|
+
const cursorRaw = c.req.query("cursor");
|
|
36540
36588
|
const limit = resolveSessionsLimit(c.req.query("limit"));
|
|
36541
|
-
const before = decodeSessionsCursor(
|
|
36542
|
-
|
|
36589
|
+
const before = decodeSessionsCursor(cursorRaw);
|
|
36590
|
+
const key = scopeCacheKey(scope, String(limit), cursorRaw);
|
|
36591
|
+
return c.json(await sessionsCache(key, () => fetchSessionsView(storage, scope, before !== void 0 ? { limit, before } : { limit })));
|
|
36543
36592
|
});
|
|
36544
36593
|
}
|
|
36545
36594
|
const settings = daemon.group(DASHBOARD_GROUPS.settings);
|
|
@@ -36562,20 +36611,22 @@ function mountDashboardApi(daemon, options) {
|
|
|
36562
36611
|
}
|
|
36563
36612
|
const rules = daemon.group(DASHBOARD_GROUPS.rules);
|
|
36564
36613
|
if (rules !== void 0) {
|
|
36614
|
+
const rulesCache = createTtlViewCache(DIAG_TTL_MS);
|
|
36565
36615
|
rules.get("/rules", async (c) => {
|
|
36566
36616
|
const scope = resolveScope5(c);
|
|
36567
36617
|
if (scope === null)
|
|
36568
36618
|
return c.json(NO_ORG_BODY4, 400);
|
|
36569
|
-
return c.json(await fetchRulesView(storage, scope));
|
|
36619
|
+
return c.json(await rulesCache(scopeCacheKey(scope), () => fetchRulesView(storage, scope)));
|
|
36570
36620
|
});
|
|
36571
36621
|
}
|
|
36572
36622
|
const skills = daemon.group(DASHBOARD_GROUPS.skills);
|
|
36573
36623
|
if (skills !== void 0) {
|
|
36624
|
+
const skillsCache = createTtlViewCache(DIAG_TTL_MS);
|
|
36574
36625
|
skills.get("/skills", async (c) => {
|
|
36575
36626
|
const scope = resolveScope5(c);
|
|
36576
36627
|
if (scope === null)
|
|
36577
36628
|
return c.json(NO_ORG_BODY4, 400);
|
|
36578
|
-
return c.json(await fetchSkillSyncView(storage, scope));
|
|
36629
|
+
return c.json(await skillsCache(scopeCacheKey(scope), () => fetchSkillSyncView(storage, scope)));
|
|
36579
36630
|
});
|
|
36580
36631
|
}
|
|
36581
36632
|
const installedAssets = daemon.group(DASHBOARD_GROUPS.installedAssets);
|
|
@@ -36626,6 +36677,535 @@ function createInventoryCache() {
|
|
|
36626
36677
|
return value;
|
|
36627
36678
|
};
|
|
36628
36679
|
}
|
|
36680
|
+
var DIAG_TTL_MS = 1e4;
|
|
36681
|
+
var SAVINGS_TTL_MS = 6e4;
|
|
36682
|
+
var CACHE_MAX_KEYS = 64;
|
|
36683
|
+
function scopeCacheKey(scope, ...extra) {
|
|
36684
|
+
return [scope.org, scope.workspace ?? "", ...extra.map((e) => e ?? "")].join("\0");
|
|
36685
|
+
}
|
|
36686
|
+
function createTtlViewCache(ttlMs) {
|
|
36687
|
+
const cache = /* @__PURE__ */ new Map();
|
|
36688
|
+
return async (key, compute) => {
|
|
36689
|
+
const now = Date.now();
|
|
36690
|
+
const hit = cache.get(key);
|
|
36691
|
+
if (hit !== void 0 && now - hit.at < ttlMs)
|
|
36692
|
+
return hit.value;
|
|
36693
|
+
const value = await compute();
|
|
36694
|
+
if (cache.size >= CACHE_MAX_KEYS && !cache.has(key))
|
|
36695
|
+
cache.clear();
|
|
36696
|
+
cache.set(key, { value, at: now });
|
|
36697
|
+
return value;
|
|
36698
|
+
};
|
|
36699
|
+
}
|
|
36700
|
+
|
|
36701
|
+
// dist/src/daemon/runtime/dashboard/actions-api.js
|
|
36702
|
+
import { spawn as spawn4 } from "node:child_process";
|
|
36703
|
+
import { rmSync as rmSync5 } from "node:fs";
|
|
36704
|
+
import { dirname as dirname12, resolve as resolve5 } from "node:path";
|
|
36705
|
+
|
|
36706
|
+
// dist/src/daemon/runtime/secrets/api.js
|
|
36707
|
+
function localDefaultScopeResolver(mode, defaultScope) {
|
|
36708
|
+
return {
|
|
36709
|
+
resolve(c) {
|
|
36710
|
+
const fromHeader = headerScopeResolver.resolve(c);
|
|
36711
|
+
if (fromHeader !== null)
|
|
36712
|
+
return fromHeader;
|
|
36713
|
+
if (mode === "local" && defaultScope !== void 0) {
|
|
36714
|
+
return { org: defaultScope.org, workspace: defaultScope.workspace ?? "default" };
|
|
36715
|
+
}
|
|
36716
|
+
return null;
|
|
36717
|
+
}
|
|
36718
|
+
};
|
|
36719
|
+
}
|
|
36720
|
+
var headerScopeResolver = {
|
|
36721
|
+
resolve(c) {
|
|
36722
|
+
const org = c.req.header("x-honeycomb-org");
|
|
36723
|
+
if (org === void 0 || org.length === 0)
|
|
36724
|
+
return null;
|
|
36725
|
+
const workspace = c.req.header("x-honeycomb-workspace");
|
|
36726
|
+
const agentId = c.req.header("x-honeycomb-agent");
|
|
36727
|
+
const ws = workspace !== void 0 && workspace.length > 0 ? workspace : "default";
|
|
36728
|
+
return agentId !== void 0 && agentId.length > 0 ? { org, workspace: ws, agentId } : { org, workspace: ws };
|
|
36729
|
+
}
|
|
36730
|
+
};
|
|
36731
|
+
function mountSecretsApi(group, deps) {
|
|
36732
|
+
const scope = deps.scope ?? headerScopeResolver;
|
|
36733
|
+
const store = deps.store;
|
|
36734
|
+
const runner = deps.execRunner;
|
|
36735
|
+
if (runner !== void 0) {
|
|
36736
|
+
group.post("/exec", async (c) => {
|
|
36737
|
+
const sc = scope.resolve(c);
|
|
36738
|
+
if (sc === null)
|
|
36739
|
+
return badTenancy(c);
|
|
36740
|
+
const request = await readExecRequest(c, sc);
|
|
36741
|
+
if (request === null) {
|
|
36742
|
+
return c.json({ error: "bad_request", reason: "exec body must carry a command" }, 400);
|
|
36743
|
+
}
|
|
36744
|
+
const res = runner.submit(request);
|
|
36745
|
+
if (!res.ok) {
|
|
36746
|
+
if (res.reason === "queue_full") {
|
|
36747
|
+
return c.json({ error: "queue_full", reason: "exec pool and queue are at capacity" }, 429);
|
|
36748
|
+
}
|
|
36749
|
+
return c.json({ error: "bad_request", reason: "invalid exec request" }, 400);
|
|
36750
|
+
}
|
|
36751
|
+
return c.json({ ok: true, jobId: res.jobId, status: "queued" }, 202);
|
|
36752
|
+
});
|
|
36753
|
+
group.get("/exec/:jobId", (c) => {
|
|
36754
|
+
const sc = scope.resolve(c);
|
|
36755
|
+
if (sc === null)
|
|
36756
|
+
return badTenancy(c);
|
|
36757
|
+
const jobId = c.req.param("jobId");
|
|
36758
|
+
const view = runner.getStatus(jobId, sc);
|
|
36759
|
+
if (view === null) {
|
|
36760
|
+
return c.json({ error: "not_found", reason: "no such exec job" }, 404);
|
|
36761
|
+
}
|
|
36762
|
+
return c.json(view);
|
|
36763
|
+
});
|
|
36764
|
+
group.all("/bitwarden/*", (c) => c.json({ error: "use_exec", reason: "reference a Bitwarden item via exec vaultRefs; values are never returned" }, 400));
|
|
36765
|
+
group.all("/1password/*", (c) => c.json({ error: "use_exec", reason: "reference a 1Password item via exec vaultRefs; values are never returned" }, 400));
|
|
36766
|
+
} else {
|
|
36767
|
+
group.post("/exec", (c) => notImplementedRoute(c, "POST /api/secrets/exec (secret_exec)"));
|
|
36768
|
+
group.get("/exec/:jobId", (c) => notImplementedRoute(c, "GET /api/secrets/exec/:jobId (exec status)"));
|
|
36769
|
+
group.all("/bitwarden/*", (c) => notImplementedRoute(c, "Bitwarden vault provider"));
|
|
36770
|
+
group.all("/1password/*", (c) => notImplementedRoute(c, "1Password vault provider"));
|
|
36771
|
+
}
|
|
36772
|
+
group.get("/", (c) => {
|
|
36773
|
+
const sc = scope.resolve(c);
|
|
36774
|
+
if (sc === null)
|
|
36775
|
+
return badTenancy(c);
|
|
36776
|
+
const names = store.listSecretNames(sc);
|
|
36777
|
+
return c.json({ names });
|
|
36778
|
+
});
|
|
36779
|
+
group.post("/:name", async (c) => {
|
|
36780
|
+
const sc = scope.resolve(c);
|
|
36781
|
+
if (sc === null)
|
|
36782
|
+
return badTenancy(c);
|
|
36783
|
+
const name = c.req.param("name");
|
|
36784
|
+
const value = await readValue(c);
|
|
36785
|
+
if (value === null) {
|
|
36786
|
+
return c.json({ error: "bad_request", reason: "request body must carry a string value" }, 400);
|
|
36787
|
+
}
|
|
36788
|
+
const res = await store.setSecret(name, value, sc);
|
|
36789
|
+
if (!res.ok) {
|
|
36790
|
+
if (res.reason === "invalid_name") {
|
|
36791
|
+
return c.json({ error: "bad_request", reason: "invalid secret name" }, 400);
|
|
36792
|
+
}
|
|
36793
|
+
return c.json({ error: "store_failed", reason: "could not store the secret" }, 502);
|
|
36794
|
+
}
|
|
36795
|
+
return c.json({ ok: true, name }, 201);
|
|
36796
|
+
});
|
|
36797
|
+
group.delete("/:name", (c) => {
|
|
36798
|
+
const sc = scope.resolve(c);
|
|
36799
|
+
if (sc === null)
|
|
36800
|
+
return badTenancy(c);
|
|
36801
|
+
const name = c.req.param("name");
|
|
36802
|
+
const res = store.deleteSecret(name, sc);
|
|
36803
|
+
if (!res.ok) {
|
|
36804
|
+
if (res.reason === "invalid_name") {
|
|
36805
|
+
return c.json({ error: "bad_request", reason: "invalid secret name" }, 400);
|
|
36806
|
+
}
|
|
36807
|
+
if (res.reason === "not_found") {
|
|
36808
|
+
return c.json({ error: "not_found", reason: "no such secret" }, 404);
|
|
36809
|
+
}
|
|
36810
|
+
return c.json({ error: "delete_failed", reason: "could not delete the secret" }, 502);
|
|
36811
|
+
}
|
|
36812
|
+
return c.json({ ok: true, name });
|
|
36813
|
+
});
|
|
36814
|
+
}
|
|
36815
|
+
function badTenancy(c) {
|
|
36816
|
+
return c.json({ error: "bad_request", reason: "x-honeycomb-org header is required" }, 400);
|
|
36817
|
+
}
|
|
36818
|
+
async function readValue(c) {
|
|
36819
|
+
const contentType = c.req.header("content-type") ?? "";
|
|
36820
|
+
if (contentType.includes("application/json")) {
|
|
36821
|
+
try {
|
|
36822
|
+
const body = await c.req.json();
|
|
36823
|
+
if (typeof body === "object" && body !== null) {
|
|
36824
|
+
const v = body.value;
|
|
36825
|
+
if (typeof v === "string" && v.length > 0)
|
|
36826
|
+
return v;
|
|
36827
|
+
}
|
|
36828
|
+
return null;
|
|
36829
|
+
} catch {
|
|
36830
|
+
return null;
|
|
36831
|
+
}
|
|
36832
|
+
}
|
|
36833
|
+
const text = await c.req.text();
|
|
36834
|
+
return text.length > 0 ? text : null;
|
|
36835
|
+
}
|
|
36836
|
+
function notImplementedRoute(c, what) {
|
|
36837
|
+
return c.json({ error: "not_implemented", reason: `${what} is implemented in PRD-012b` }, 501);
|
|
36838
|
+
}
|
|
36839
|
+
async function readExecRequest(c, scope) {
|
|
36840
|
+
let body;
|
|
36841
|
+
try {
|
|
36842
|
+
body = await c.req.json();
|
|
36843
|
+
} catch {
|
|
36844
|
+
return null;
|
|
36845
|
+
}
|
|
36846
|
+
if (typeof body !== "object" || body === null)
|
|
36847
|
+
return null;
|
|
36848
|
+
const b = body;
|
|
36849
|
+
const command = b.command;
|
|
36850
|
+
if (typeof command !== "string" || command.length === 0)
|
|
36851
|
+
return null;
|
|
36852
|
+
const args = Array.isArray(b.args) ? b.args.filter((a) => typeof a === "string") : [];
|
|
36853
|
+
const secretNames = Array.isArray(b.secretNames) ? b.secretNames.filter((n) => typeof n === "string") : [];
|
|
36854
|
+
const vaultRefs = {};
|
|
36855
|
+
if (typeof b.vaultRefs === "object" && b.vaultRefs !== null) {
|
|
36856
|
+
for (const [k, v] of Object.entries(b.vaultRefs)) {
|
|
36857
|
+
if (typeof v === "string")
|
|
36858
|
+
vaultRefs[k] = v;
|
|
36859
|
+
}
|
|
36860
|
+
}
|
|
36861
|
+
const timeoutMs = typeof b.timeoutMs === "number" ? b.timeoutMs : void 0;
|
|
36862
|
+
return { command, args, secretNames, vaultRefs, scope, timeoutMs };
|
|
36863
|
+
}
|
|
36864
|
+
|
|
36865
|
+
// dist/src/daemon/runtime/vault/catalog.js
|
|
36866
|
+
var PROVIDER_CATALOG = Object.freeze([
|
|
36867
|
+
Object.freeze({
|
|
36868
|
+
id: "anthropic",
|
|
36869
|
+
label: "Anthropic",
|
|
36870
|
+
models: Object.freeze(["claude-sonnet-4-6", "claude-opus-4-8"]),
|
|
36871
|
+
openEnded: false
|
|
36872
|
+
}),
|
|
36873
|
+
Object.freeze({
|
|
36874
|
+
id: "openai",
|
|
36875
|
+
label: "OpenAI",
|
|
36876
|
+
models: Object.freeze(["gpt-4o", "gpt-4o-mini", "gpt-4.1"]),
|
|
36877
|
+
openEnded: false
|
|
36878
|
+
}),
|
|
36879
|
+
Object.freeze({
|
|
36880
|
+
id: "openrouter",
|
|
36881
|
+
label: "OpenRouter",
|
|
36882
|
+
// Suggestions only — OpenRouter accepts a free-form `vendor/model` id (passthrough).
|
|
36883
|
+
models: Object.freeze(["anthropic/claude-sonnet-4.6", "openai/gpt-4o"]),
|
|
36884
|
+
openEnded: true
|
|
36885
|
+
}),
|
|
36886
|
+
Object.freeze({
|
|
36887
|
+
// PRD-063a: Portkey is a GATEWAY, not a model vendor — its `portkey.config` id is
|
|
36888
|
+
// free-form (a config or virtual-key id copied from the Portkey dashboard), so it is
|
|
36889
|
+
// `openEnded: true` like OpenRouter and carries NO curated model list of its own.
|
|
36890
|
+
id: "portkey",
|
|
36891
|
+
label: "Portkey",
|
|
36892
|
+
models: Object.freeze([]),
|
|
36893
|
+
openEnded: true
|
|
36894
|
+
})
|
|
36895
|
+
]);
|
|
36896
|
+
function providerEntry(provider) {
|
|
36897
|
+
return PROVIDER_CATALOG.find((p) => p.id === provider);
|
|
36898
|
+
}
|
|
36899
|
+
function isValidProviderModel(provider, model) {
|
|
36900
|
+
const entry = providerEntry(provider);
|
|
36901
|
+
if (entry === void 0)
|
|
36902
|
+
return false;
|
|
36903
|
+
if (typeof model !== "string" || model.length === 0)
|
|
36904
|
+
return false;
|
|
36905
|
+
if (entry.openEnded)
|
|
36906
|
+
return true;
|
|
36907
|
+
return entry.models.includes(model);
|
|
36908
|
+
}
|
|
36909
|
+
function catalogView() {
|
|
36910
|
+
return PROVIDER_CATALOG;
|
|
36911
|
+
}
|
|
36912
|
+
|
|
36913
|
+
// dist/src/daemon/runtime/secrets/contracts.js
|
|
36914
|
+
import { homedir as homedir12, hostname as hostname3, userInfo } from "node:os";
|
|
36915
|
+
var SECRET_NAME_PATTERN = /^[A-Za-z0-9_.-]+$/;
|
|
36916
|
+
var MAX_SECRET_NAME_LENGTH = 128;
|
|
36917
|
+
function isValidSecretName(value) {
|
|
36918
|
+
if (typeof value !== "string")
|
|
36919
|
+
return false;
|
|
36920
|
+
if (value.length === 0 || value.length > MAX_SECRET_NAME_LENGTH)
|
|
36921
|
+
return false;
|
|
36922
|
+
if (value === "." || value === "..")
|
|
36923
|
+
return false;
|
|
36924
|
+
if (value.includes("/") || value.includes("\\") || value.includes("\0"))
|
|
36925
|
+
return false;
|
|
36926
|
+
return SECRET_NAME_PATTERN.test(value);
|
|
36927
|
+
}
|
|
36928
|
+
function asSecretName(value) {
|
|
36929
|
+
return isValidSecretName(value) ? value : null;
|
|
36930
|
+
}
|
|
36931
|
+
function isSecretRecord(value) {
|
|
36932
|
+
if (typeof value !== "object" || value === null)
|
|
36933
|
+
return false;
|
|
36934
|
+
const r = value;
|
|
36935
|
+
if (typeof r.nonce !== "string" || typeof r.ciphertext !== "string" || typeof r.createdAt !== "string") {
|
|
36936
|
+
return false;
|
|
36937
|
+
}
|
|
36938
|
+
const scope = r.scope;
|
|
36939
|
+
if (typeof scope !== "object" || scope === null)
|
|
36940
|
+
return false;
|
|
36941
|
+
const s = scope;
|
|
36942
|
+
if (typeof s.org !== "string" || typeof s.workspace !== "string")
|
|
36943
|
+
return false;
|
|
36944
|
+
if (s.agentId !== void 0 && typeof s.agentId !== "string")
|
|
36945
|
+
return false;
|
|
36946
|
+
return true;
|
|
36947
|
+
}
|
|
36948
|
+
var MACHINE_KEY_DIR_NAME = ".honeycomb";
|
|
36949
|
+
var MACHINE_KEY_FILE_NAME = ".machine-key";
|
|
36950
|
+
function hostnameUserFallbackId() {
|
|
36951
|
+
let user = "";
|
|
36952
|
+
try {
|
|
36953
|
+
user = userInfo().username;
|
|
36954
|
+
} catch {
|
|
36955
|
+
user = "";
|
|
36956
|
+
}
|
|
36957
|
+
return `host:${hostname3()}|user:${user}|home:${homedir12()}`;
|
|
36958
|
+
}
|
|
36959
|
+
|
|
36960
|
+
// dist/src/daemon/runtime/vault/contracts.js
|
|
36961
|
+
function asRecordClass(value) {
|
|
36962
|
+
return isValidSecretName(value) ? value : null;
|
|
36963
|
+
}
|
|
36964
|
+
|
|
36965
|
+
// dist/src/daemon/runtime/vault/registry.js
|
|
36966
|
+
var SECRET_CLASS = "secret";
|
|
36967
|
+
var SETTING_CLASS = "setting";
|
|
36968
|
+
var SecretValueSchema = external_exports.string().min(1);
|
|
36969
|
+
var SettingValueSchema = external_exports.union([external_exports.string(), external_exports.number().finite(), external_exports.boolean()]);
|
|
36970
|
+
var SECRET_DESCRIPTOR = Object.freeze({
|
|
36971
|
+
id: SECRET_CLASS,
|
|
36972
|
+
posture: "internal-only",
|
|
36973
|
+
schema: SecretValueSchema
|
|
36974
|
+
});
|
|
36975
|
+
var SETTING_DESCRIPTOR = Object.freeze({
|
|
36976
|
+
id: SETTING_CLASS,
|
|
36977
|
+
posture: "daemon-readable",
|
|
36978
|
+
schema: SettingValueSchema
|
|
36979
|
+
});
|
|
36980
|
+
var VaultRegistry = class {
|
|
36981
|
+
table;
|
|
36982
|
+
constructor(descriptors) {
|
|
36983
|
+
this.table = /* @__PURE__ */ new Map();
|
|
36984
|
+
for (const d of descriptors)
|
|
36985
|
+
this.table.set(d.id, d);
|
|
36986
|
+
}
|
|
36987
|
+
/**
|
|
36988
|
+
* Register a new record class (D-7). Validates the id is traversal-proof (a class is an
|
|
36989
|
+
* on-disk segment) and that the posture is one the store understands, then adds the
|
|
36990
|
+
* descriptor. Re-registering an existing id REPLACES it (so a test can swap a throwaway
|
|
36991
|
+
* class); registering the built-in `secret`/`setting` ids is allowed but discouraged —
|
|
36992
|
+
* their posture must not be loosened. Returns the registry for chaining.
|
|
36993
|
+
*
|
|
36994
|
+
* Throws on an invalid (traversal-unsafe) class id — that is a programming error, not a
|
|
36995
|
+
* runtime input, so it fails loud rather than silently dropping the class.
|
|
36996
|
+
*/
|
|
36997
|
+
registerClass(descriptor) {
|
|
36998
|
+
const safe = asRecordClass(descriptor.id);
|
|
36999
|
+
if (safe === null) {
|
|
37000
|
+
throw new Error(`vault.registerClass: invalid (traversal-unsafe) class id`);
|
|
37001
|
+
}
|
|
37002
|
+
this.table.set(descriptor.id, descriptor);
|
|
37003
|
+
return this;
|
|
37004
|
+
}
|
|
37005
|
+
/** Whether a class id is registered. */
|
|
37006
|
+
has(klass) {
|
|
37007
|
+
return this.table.has(klass);
|
|
37008
|
+
}
|
|
37009
|
+
/** The registered class ids (sorted), for diagnostics — never values. */
|
|
37010
|
+
classIds() {
|
|
37011
|
+
return [...this.table.keys()].sort();
|
|
37012
|
+
}
|
|
37013
|
+
/**
|
|
37014
|
+
* Resolve a class's descriptor for a WRITE, validating the value against the class
|
|
37015
|
+
* schema (zod-at-boundary). Returns `unknown_class` for an unregistered class or
|
|
37016
|
+
* `invalid_value` when the value fails the schema — both fail-closed (nothing is
|
|
37017
|
+
* written). On success the descriptor (with the validated value available via the
|
|
37018
|
+
* caller's re-parse) is returned.
|
|
37019
|
+
*/
|
|
37020
|
+
resolveForWrite(klass, value) {
|
|
37021
|
+
const descriptor = this.table.get(klass);
|
|
37022
|
+
if (descriptor === void 0)
|
|
37023
|
+
return { ok: false, reason: "unknown_class" };
|
|
37024
|
+
const parsed = descriptor.schema.safeParse(value);
|
|
37025
|
+
if (!parsed.success)
|
|
37026
|
+
return { ok: false, reason: "invalid_value" };
|
|
37027
|
+
return { ok: true, descriptor };
|
|
37028
|
+
}
|
|
37029
|
+
/**
|
|
37030
|
+
* The POSTURE GATE (a-AC-2). Resolve a class's descriptor for a READ that intends to
|
|
37031
|
+
* RETURN the value to a surface (the `getSetting` path). REJECTS a class whose posture
|
|
37032
|
+
* is `internal-only` with `not_readable` — so a `secret` can NEVER be read back through
|
|
37033
|
+
* the daemon-readable accessor. An unknown class is `unknown_class`. This is the single
|
|
37034
|
+
* point where the secret-vs-setting security boundary is enforced, as data.
|
|
37035
|
+
*/
|
|
37036
|
+
assertReadable(klass) {
|
|
37037
|
+
const descriptor = this.table.get(klass);
|
|
37038
|
+
if (descriptor === void 0)
|
|
37039
|
+
return { ok: false, reason: "unknown_class" };
|
|
37040
|
+
if (descriptor.posture !== "daemon-readable")
|
|
37041
|
+
return { ok: false, reason: "not_readable" };
|
|
37042
|
+
return { ok: true, descriptor };
|
|
37043
|
+
}
|
|
37044
|
+
/** Resolve a descriptor with no value/posture check (internal callers that already gate). */
|
|
37045
|
+
descriptorOf(klass) {
|
|
37046
|
+
return this.table.get(klass);
|
|
37047
|
+
}
|
|
37048
|
+
};
|
|
37049
|
+
function createVaultRegistry(extra = []) {
|
|
37050
|
+
return new VaultRegistry([SECRET_DESCRIPTOR, SETTING_DESCRIPTOR, ...extra]);
|
|
37051
|
+
}
|
|
37052
|
+
|
|
37053
|
+
// dist/src/daemon/runtime/vault/api.js
|
|
37054
|
+
var SETTINGS_GROUP = "/api/settings";
|
|
37055
|
+
var EMBEDDINGS_ENABLED_KEY = "embeddings.enabled";
|
|
37056
|
+
var KNOWN_SETTING_KEYS = [
|
|
37057
|
+
"activeProvider",
|
|
37058
|
+
"activeModel",
|
|
37059
|
+
"pollinating.enabled",
|
|
37060
|
+
EMBEDDINGS_ENABLED_KEY,
|
|
37061
|
+
"recallMode",
|
|
37062
|
+
"portkey.enabled",
|
|
37063
|
+
"portkey.config",
|
|
37064
|
+
"portkey.fallbackToProvider"
|
|
37065
|
+
];
|
|
37066
|
+
var RECALL_MODES = ["keyword", "semantic", "hybrid"];
|
|
37067
|
+
function isValidRecallMode(value) {
|
|
37068
|
+
return RECALL_MODES.includes(value);
|
|
37069
|
+
}
|
|
37070
|
+
var DASHBOARD_PREF_PREFIX = "dashboard.";
|
|
37071
|
+
function isKnownSettingKey(key) {
|
|
37072
|
+
if (KNOWN_SETTING_KEYS.includes(key))
|
|
37073
|
+
return true;
|
|
37074
|
+
return key.startsWith(DASHBOARD_PREF_PREFIX) && key.length > DASHBOARD_PREF_PREFIX.length;
|
|
37075
|
+
}
|
|
37076
|
+
function mountSettingsGroup(group, deps) {
|
|
37077
|
+
const scope = deps.scope ?? headerScopeResolver;
|
|
37078
|
+
const store = deps.store;
|
|
37079
|
+
group.get("/", async (c) => {
|
|
37080
|
+
const sc = scope.resolve(c);
|
|
37081
|
+
if (sc === null)
|
|
37082
|
+
return badTenancy2(c);
|
|
37083
|
+
const keys = store.listSettingKeys(sc);
|
|
37084
|
+
const settings = {};
|
|
37085
|
+
for (const key of keys) {
|
|
37086
|
+
const res = await store.getSetting(key, sc);
|
|
37087
|
+
if (res.ok)
|
|
37088
|
+
settings[key] = res.value;
|
|
37089
|
+
}
|
|
37090
|
+
return c.json({ settings, catalog: catalogView() });
|
|
37091
|
+
});
|
|
37092
|
+
group.get("/:key", async (c) => {
|
|
37093
|
+
const sc = scope.resolve(c);
|
|
37094
|
+
if (sc === null)
|
|
37095
|
+
return badTenancy2(c);
|
|
37096
|
+
const key = c.req.param("key");
|
|
37097
|
+
if (!isKnownSettingKey(key)) {
|
|
37098
|
+
return c.json({ error: "not_found", reason: "no such setting" }, 404);
|
|
37099
|
+
}
|
|
37100
|
+
const res = await store.getSetting(key, sc);
|
|
37101
|
+
if (!res.ok) {
|
|
37102
|
+
if (res.reason === "not_found")
|
|
37103
|
+
return c.json({ error: "not_found", reason: "no such setting" }, 404);
|
|
37104
|
+
if (res.reason === "not_readable")
|
|
37105
|
+
return c.json({ error: "not_found", reason: "no such setting" }, 404);
|
|
37106
|
+
return c.json({ error: "read_failed", reason: "could not read the setting" }, 502);
|
|
37107
|
+
}
|
|
37108
|
+
return c.json({ key, value: res.value });
|
|
37109
|
+
});
|
|
37110
|
+
group.post("/:key", async (c) => {
|
|
37111
|
+
const sc = scope.resolve(c);
|
|
37112
|
+
if (sc === null)
|
|
37113
|
+
return badTenancy2(c);
|
|
37114
|
+
const key = c.req.param("key");
|
|
37115
|
+
if (!isKnownSettingKey(key)) {
|
|
37116
|
+
return c.json({ error: "bad_request", reason: "unknown setting key" }, 400);
|
|
37117
|
+
}
|
|
37118
|
+
const value = await readSettingValue(c);
|
|
37119
|
+
if (value === null) {
|
|
37120
|
+
return c.json({ error: "bad_request", reason: "request body must carry a scalar value" }, 400);
|
|
37121
|
+
}
|
|
37122
|
+
const semanticError = await validateSettingSemantics(store, sc, key, value);
|
|
37123
|
+
if (semanticError !== null) {
|
|
37124
|
+
return c.json({ error: "bad_request", reason: semanticError }, 400);
|
|
37125
|
+
}
|
|
37126
|
+
const res = await store.setSetting(key, value, sc);
|
|
37127
|
+
if (!res.ok) {
|
|
37128
|
+
if (res.reason === "invalid_value") {
|
|
37129
|
+
return c.json({ error: "bad_request", reason: "invalid setting value" }, 400);
|
|
37130
|
+
}
|
|
37131
|
+
if (res.reason === "not_readable" || res.reason === "unknown_class") {
|
|
37132
|
+
return c.json({ error: "bad_request", reason: "setting class is not writable" }, 400);
|
|
37133
|
+
}
|
|
37134
|
+
return c.json({ error: "store_failed", reason: "could not store the setting" }, 502);
|
|
37135
|
+
}
|
|
37136
|
+
return c.json({ ok: true, key, value }, 201);
|
|
37137
|
+
});
|
|
37138
|
+
}
|
|
37139
|
+
function mountSettingsApi(daemon, deps) {
|
|
37140
|
+
const group = daemon.group(SETTINGS_GROUP);
|
|
37141
|
+
if (group === void 0)
|
|
37142
|
+
return;
|
|
37143
|
+
mountSettingsGroup(group, deps);
|
|
37144
|
+
}
|
|
37145
|
+
function badTenancy2(c) {
|
|
37146
|
+
return c.json({ error: "bad_request", reason: "x-honeycomb-org header is required" }, 400);
|
|
37147
|
+
}
|
|
37148
|
+
async function readSettingValue(c) {
|
|
37149
|
+
const contentType = c.req.header("content-type") ?? "";
|
|
37150
|
+
if (contentType.includes("application/json")) {
|
|
37151
|
+
try {
|
|
37152
|
+
const body = await c.req.json();
|
|
37153
|
+
if (typeof body === "object" && body !== null) {
|
|
37154
|
+
const v = body.value;
|
|
37155
|
+
const parsed = SettingValueSchema.safeParse(v);
|
|
37156
|
+
return parsed.success ? parsed.data : null;
|
|
37157
|
+
}
|
|
37158
|
+
return null;
|
|
37159
|
+
} catch {
|
|
37160
|
+
return null;
|
|
37161
|
+
}
|
|
37162
|
+
}
|
|
37163
|
+
const text = await c.req.text();
|
|
37164
|
+
return text.length > 0 ? text : null;
|
|
37165
|
+
}
|
|
37166
|
+
async function validateSettingSemantics(store, scope, key, value) {
|
|
37167
|
+
if (key === "activeProvider") {
|
|
37168
|
+
if (providerEntry(String(value)) === void 0)
|
|
37169
|
+
return "unknown provider";
|
|
37170
|
+
return null;
|
|
37171
|
+
}
|
|
37172
|
+
if (key === "activeModel") {
|
|
37173
|
+
const provRes = await store.getSetting("activeProvider", scope);
|
|
37174
|
+
const provider = provRes.ok ? String(provRes.value) : "";
|
|
37175
|
+
if (provider.length === 0)
|
|
37176
|
+
return "set activeProvider before activeModel";
|
|
37177
|
+
if (!isValidProviderModel(provider, String(value)))
|
|
37178
|
+
return "model not in provider catalog";
|
|
37179
|
+
return null;
|
|
37180
|
+
}
|
|
37181
|
+
if (key === "recallMode") {
|
|
37182
|
+
if (!isValidRecallMode(String(value)))
|
|
37183
|
+
return "recallMode must be keyword, semantic, or hybrid";
|
|
37184
|
+
return null;
|
|
37185
|
+
}
|
|
37186
|
+
if (key === "portkey.enabled" || key === "portkey.fallbackToProvider") {
|
|
37187
|
+
if (typeof value !== "boolean")
|
|
37188
|
+
return `${key} must be a boolean`;
|
|
37189
|
+
return null;
|
|
37190
|
+
}
|
|
37191
|
+
if (key === "portkey.config") {
|
|
37192
|
+
if (typeof value !== "string")
|
|
37193
|
+
return "portkey.config must be a string";
|
|
37194
|
+
if (/[\u0000-\u001F\u007F]/.test(value))
|
|
37195
|
+
return "portkey.config must not contain control characters";
|
|
37196
|
+
const enabledRes = await store.getSetting("portkey.enabled", scope);
|
|
37197
|
+
const enabled = enabledRes.ok && enabledRes.value === true;
|
|
37198
|
+
if (enabled && value.length === 0)
|
|
37199
|
+
return "portkey.config must be non-empty when portkey.enabled is true";
|
|
37200
|
+
return null;
|
|
37201
|
+
}
|
|
37202
|
+
return null;
|
|
37203
|
+
}
|
|
37204
|
+
|
|
37205
|
+
// dist/src/daemon/runtime/dashboard/harness-detect.js
|
|
37206
|
+
import { existsSync as existsSync12 } from "node:fs";
|
|
37207
|
+
import { homedir as homedir16 } from "node:os";
|
|
37208
|
+
import { join as join20 } from "node:path";
|
|
36629
37209
|
|
|
36630
37210
|
// dist/src/hooks/shared/contracts.js
|
|
36631
37211
|
var LOGICAL_EVENTS = [
|
|
@@ -36730,7 +37310,7 @@ var HEALTH_DIMENSION_WIRABLE = Object.freeze({
|
|
|
36730
37310
|
|
|
36731
37311
|
// dist/src/notifications/state.js
|
|
36732
37312
|
import { closeSync as closeSync3, existsSync as existsSync10, mkdirSync as mkdirSync11, openSync as openSync3, readFileSync as readFileSync13, renameSync as renameSync6, unlinkSync as unlinkSync2, writeFileSync as writeFileSync9 } from "node:fs";
|
|
36733
|
-
import { homedir as
|
|
37313
|
+
import { homedir as homedir13 } from "node:os";
|
|
36734
37314
|
import { join as join17 } from "node:path";
|
|
36735
37315
|
|
|
36736
37316
|
// dist/src/daemon/runtime/assets/contracts.js
|
|
@@ -36754,7 +37334,7 @@ var audienceMatches = (asset, ctx) => {
|
|
|
36754
37334
|
|
|
36755
37335
|
// dist/src/daemon-client/assets/install.js
|
|
36756
37336
|
import { existsSync as existsSync11, mkdirSync as mkdirSync12, readFileSync as readFileSync14, renameSync as renameSync7, rmSync as rmSync4, writeFileSync as writeFileSync10 } from "node:fs";
|
|
36757
|
-
import { homedir as
|
|
37337
|
+
import { homedir as homedir14 } from "node:os";
|
|
36758
37338
|
import { dirname as dirname10, join as join18, resolve as resolve4 } from "node:path";
|
|
36759
37339
|
var HARNESS_SKILL_DIRS = Object.freeze({
|
|
36760
37340
|
claude_code: join18(".claude", "skills"),
|
|
@@ -36774,38 +37354,52 @@ var HARNESS_AGENT_DIRS = Object.freeze({
|
|
|
36774
37354
|
});
|
|
36775
37355
|
|
|
36776
37356
|
// dist/src/commands/contracts.js
|
|
37357
|
+
var VERB_GROUPS = Object.freeze([
|
|
37358
|
+
{ key: "memory", label: "Memory & recall" },
|
|
37359
|
+
{ key: "knowledge", label: "Knowledge & skills" },
|
|
37360
|
+
{ key: "agents", label: "Agents, routing & config" },
|
|
37361
|
+
{ key: "account", label: "Account & workspaces" },
|
|
37362
|
+
{ key: "system", label: "Setup & system" }
|
|
37363
|
+
]);
|
|
36777
37364
|
var VERB_TABLE = Object.freeze([
|
|
36778
|
-
|
|
36779
|
-
{ verb: "
|
|
36780
|
-
{ verb: "
|
|
36781
|
-
{ verb: "
|
|
36782
|
-
{ verb: "
|
|
36783
|
-
{ verb: "
|
|
36784
|
-
{ verb: "
|
|
36785
|
-
|
|
36786
|
-
{ verb: "
|
|
36787
|
-
{ verb: "
|
|
36788
|
-
{ verb: "
|
|
36789
|
-
{ verb: "
|
|
36790
|
-
{ verb: "
|
|
36791
|
-
{ verb: "
|
|
36792
|
-
{ verb: "
|
|
36793
|
-
|
|
36794
|
-
{ verb: "
|
|
36795
|
-
{ verb: "
|
|
36796
|
-
{ verb: "
|
|
36797
|
-
{ verb: "
|
|
36798
|
-
|
|
36799
|
-
{ verb: "
|
|
36800
|
-
{ verb: "
|
|
36801
|
-
{ verb: "whoami", cls: "auth", summary: "show the authenticated user, org, and workspace (GET /me)" },
|
|
36802
|
-
{ verb: "org", cls: "auth", summary: "list/switch org (passthrough to the auth dispatcher)" },
|
|
36803
|
-
{ verb: "workspace", cls: "auth", summary: "list/switch/use workspace (passthrough to the auth dispatcher)" },
|
|
36804
|
-
{ verb: "workspaces", cls: "auth", summary: "list workspaces in the active org (alias of `workspace list`)" },
|
|
36805
|
-
{ verb: "project", cls: "auth", summary: "list/bind/use projects + show the resolved per-folder scope (049d)" },
|
|
36806
|
-
|
|
36807
|
-
{ verb: "
|
|
36808
|
-
{ verb: "
|
|
37365
|
+
// Memory & recall — the product's core write/read/lifecycle surface.
|
|
37366
|
+
{ verb: "remember", cls: "storage", group: "memory", summary: "write a memory through the daemon (--type fact|convention|preference|decision|gotcha|reference)" },
|
|
37367
|
+
{ verb: "recall", cls: "storage", group: "memory", summary: "recall memories through the daemon" },
|
|
37368
|
+
{ verb: "memory", cls: "storage", group: "memory", summary: "lifecycle: conflicts (list/resolve), stale-refs (list), inspect <id> --lifecycle (058d)" },
|
|
37369
|
+
{ verb: "sessions", cls: "storage", group: "memory", summary: "list/prune captured sessions through the daemon" },
|
|
37370
|
+
{ verb: "pollinate", cls: "storage", group: "memory", summary: "trigger a pollinating consolidation pass on the daemon (009/026)" },
|
|
37371
|
+
{ verb: "maintenance", cls: "storage", group: "memory", summary: "run version-history compaction over version-bumped tables (030)" },
|
|
37372
|
+
// Knowledge & skills — skills, assets, ontology, the codebase graph, and goals.
|
|
37373
|
+
{ verb: "skill", cls: "storage", group: "knowledge", summary: "skillify scope/pull/unpull/force/promote through the daemon (promote = cross-project, 049c)" },
|
|
37374
|
+
{ verb: "skillify", cls: "storage", group: "knowledge", summary: "pull team skills from the daemon (016c)" },
|
|
37375
|
+
{ verb: "asset", cls: "storage", group: "knowledge", summary: "register/promote/demote/style skills+agents through the tier\xD7style lattice (033)" },
|
|
37376
|
+
{ verb: "ontology", cls: "storage", group: "knowledge", summary: "inspect/propose ontology changes through the daemon" },
|
|
37377
|
+
{ verb: "graph", cls: "storage", group: "knowledge", summary: "build/query the codebase graph through the daemon" },
|
|
37378
|
+
{ verb: "sources", cls: "storage", group: "knowledge", summary: "connect/index/purge sources through the daemon" },
|
|
37379
|
+
{ verb: "goal", cls: "storage", group: "knowledge", summary: "manage goals/KPIs through the daemon" },
|
|
37380
|
+
// Agents, routing & config — agent turns, inference routes, secrets, and vault settings.
|
|
37381
|
+
{ verb: "agent", cls: "storage", group: "agents", summary: "run an agent turn through the daemon" },
|
|
37382
|
+
{ verb: "route", cls: "storage", group: "agents", summary: "manage inference routes through the daemon" },
|
|
37383
|
+
{ verb: "secret", cls: "storage", group: "agents", summary: "manage named secrets through the daemon" },
|
|
37384
|
+
{ verb: "settings", cls: "storage", group: "agents", summary: "get/set/list vault settings + provider\u2192model selector through the daemon" },
|
|
37385
|
+
// Account & workspaces — auth, identity, and the org/workspace/project scope surface.
|
|
37386
|
+
{ verb: "login", cls: "auth", group: "account", summary: "authenticate via device flow, or --token <key> for headless (023)" },
|
|
37387
|
+
{ verb: "logout", cls: "auth", group: "account", summary: "remove the shared credentials and sign out (023)" },
|
|
37388
|
+
{ verb: "whoami", cls: "auth", group: "account", summary: "show the authenticated user, org, and workspace (GET /me)" },
|
|
37389
|
+
{ verb: "org", cls: "auth", group: "account", summary: "list/switch org (passthrough to the auth dispatcher)" },
|
|
37390
|
+
{ verb: "workspace", cls: "auth", group: "account", summary: "list/switch/use workspace (passthrough to the auth dispatcher)" },
|
|
37391
|
+
{ verb: "workspaces", cls: "auth", group: "account", summary: "list workspaces in the active org (alias of `workspace list`)" },
|
|
37392
|
+
{ verb: "project", cls: "auth", group: "account", summary: "list/bind/use projects + show the resolved per-folder scope (049d)" },
|
|
37393
|
+
// Setup & system — install/onboard, daemon lifecycle, dashboard, hooks, telemetry, update.
|
|
37394
|
+
{ verb: "setup", cls: "local", group: "system", summary: "detect assistants, wire hooks, bring up the daemon" },
|
|
37395
|
+
{ verb: "install", cls: "local", group: "system", summary: "bring up the daemon (health-gated) + open the dashboard (PRD-050a)" },
|
|
37396
|
+
{ verb: "status", cls: "local", group: "system", summary: "daemon connectivity + login + D1\u2013D5 environment health" },
|
|
37397
|
+
{ verb: "daemon", cls: "local", group: "system", summary: "start | stop | status the loopback daemon (3850)" },
|
|
37398
|
+
{ verb: "dashboard", cls: "local", group: "system", summary: "launch the daemon-served dashboard (020b)" },
|
|
37399
|
+
{ verb: "hook", cls: "local", group: "system", summary: "inspect/wire harness hooks" },
|
|
37400
|
+
{ verb: "telemetry", cls: "local", group: "system", summary: "show exactly what adoption telemetry has been / would be sent (--show, PRD-050e)" },
|
|
37401
|
+
{ verb: "update", cls: "local", group: "system", summary: "self-update the CLI, daemon, and bundles" },
|
|
37402
|
+
{ verb: "uninstall", cls: "local", group: "system", summary: "reverse only Honeycomb's changes" }
|
|
36809
37403
|
]);
|
|
36810
37404
|
var DEFAULT_GLOBAL_FLAGS = Object.freeze({
|
|
36811
37405
|
help: false,
|
|
@@ -36817,7 +37411,7 @@ var DEFAULT_GLOBAL_FLAGS = Object.freeze({
|
|
|
36817
37411
|
// dist/src/daemon/runtime/assets/device.js
|
|
36818
37412
|
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
36819
37413
|
import { mkdirSync as mkdirSync13, readFileSync as readFileSync15, writeFileSync as writeFileSync11 } from "node:fs";
|
|
36820
|
-
import { homedir as
|
|
37414
|
+
import { homedir as homedir15, hostname as hostname4 } from "node:os";
|
|
36821
37415
|
import { dirname as dirname11, join as join19 } from "node:path";
|
|
36822
37416
|
|
|
36823
37417
|
// dist/src/hooks/normalize.js
|
|
@@ -37342,6 +37936,200 @@ function capabilitiesFor(name) {
|
|
|
37342
37936
|
return HARNESS_CAPABILITIES[name];
|
|
37343
37937
|
}
|
|
37344
37938
|
|
|
37939
|
+
// dist/src/daemon/runtime/dashboard/harness-detect.js
|
|
37940
|
+
var HARNESS_MARKERS = [
|
|
37941
|
+
{
|
|
37942
|
+
name: "claude-code",
|
|
37943
|
+
// src/connectors/claude-code.ts: configPath() = ~/.claude/settings.json; pluginRoot = ~/.claude/plugins/honeycomb.
|
|
37944
|
+
paths: (h) => [join20(h, ".claude", "settings.json"), join20(h, ".claude", "plugins", "honeycomb")]
|
|
37945
|
+
},
|
|
37946
|
+
{
|
|
37947
|
+
name: "cursor",
|
|
37948
|
+
// src/connectors/cursor.ts: configPath() = ~/.cursor/hooks.json; pluginRoot = ~/.cursor/honeycomb.
|
|
37949
|
+
paths: (h) => [join20(h, ".cursor", "hooks.json"), join20(h, ".cursor", "honeycomb")]
|
|
37950
|
+
},
|
|
37951
|
+
{
|
|
37952
|
+
name: "codex",
|
|
37953
|
+
// hivemind-v1/src/cli/install-codex.ts: HOOKS_PATH = ~/.codex/hooks.json; PLUGIN_DIR = ~/.codex/hivemind.
|
|
37954
|
+
paths: (h) => [join20(h, ".codex", "hooks.json"), join20(h, ".codex", "hivemind")]
|
|
37955
|
+
},
|
|
37956
|
+
{
|
|
37957
|
+
name: "hermes",
|
|
37958
|
+
// hivemind-v1/src/cli/install-hermes.ts: CONFIG_PATH = ~/.hermes/config.yaml; HIVEMIND_DIR = ~/.hermes/hivemind.
|
|
37959
|
+
paths: (h) => [join20(h, ".hermes", "config.yaml"), join20(h, ".hermes", "hivemind")]
|
|
37960
|
+
},
|
|
37961
|
+
{
|
|
37962
|
+
name: "pi",
|
|
37963
|
+
// hivemind-v1/src/cli/install-pi.ts: AGENTS_MD = ~/.pi/agent/AGENTS.md; EXTENSION_PATH = ~/.pi/agent/extensions/hivemind.ts.
|
|
37964
|
+
paths: (h) => [
|
|
37965
|
+
join20(h, ".pi", "agent", "extensions", "hivemind.ts"),
|
|
37966
|
+
join20(h, ".pi", "agent", "AGENTS.md")
|
|
37967
|
+
]
|
|
37968
|
+
},
|
|
37969
|
+
{
|
|
37970
|
+
name: "openclaw",
|
|
37971
|
+
// hivemind-v1/src/cli/install-openclaw.ts: PLUGIN_DIR = ~/.openclaw/extensions/hivemind.
|
|
37972
|
+
paths: (h) => [join20(h, ".openclaw", "extensions", "hivemind")]
|
|
37973
|
+
}
|
|
37974
|
+
];
|
|
37975
|
+
function markerExists(path4) {
|
|
37976
|
+
try {
|
|
37977
|
+
return existsSync12(path4);
|
|
37978
|
+
} catch {
|
|
37979
|
+
return false;
|
|
37980
|
+
}
|
|
37981
|
+
}
|
|
37982
|
+
function detectInstalledHarnesses(homeDir = homedir16(), _cwd = process.cwd()) {
|
|
37983
|
+
const canonical = new Set(CANONICAL_HARNESS_IDS);
|
|
37984
|
+
const installed = /* @__PURE__ */ new Set();
|
|
37985
|
+
for (const marker of HARNESS_MARKERS) {
|
|
37986
|
+
if (!canonical.has(marker.name))
|
|
37987
|
+
continue;
|
|
37988
|
+
if (marker.paths(homeDir).some(markerExists))
|
|
37989
|
+
installed.add(marker.name);
|
|
37990
|
+
}
|
|
37991
|
+
return installed;
|
|
37992
|
+
}
|
|
37993
|
+
|
|
37994
|
+
// dist/src/daemon/runtime/dashboard/actions-api.js
|
|
37995
|
+
var ACTIONS_GROUP = "/api/actions";
|
|
37996
|
+
var RESTART_SHUTDOWN_DELAY_MS = 100;
|
|
37997
|
+
function isLoopbackOrigin(origin) {
|
|
37998
|
+
try {
|
|
37999
|
+
const host = new URL(origin).hostname;
|
|
38000
|
+
return host === "127.0.0.1" || host === "localhost" || host === "::1" || host === "[::1]";
|
|
38001
|
+
} catch {
|
|
38002
|
+
return false;
|
|
38003
|
+
}
|
|
38004
|
+
}
|
|
38005
|
+
function actionGuard(c, mode) {
|
|
38006
|
+
if (mode !== "local") {
|
|
38007
|
+
return c.json({ error: "forbidden", reason: "actions are available in local mode only" }, 403);
|
|
38008
|
+
}
|
|
38009
|
+
const site = c.req.header("sec-fetch-site");
|
|
38010
|
+
if (site === "cross-site" || site === "same-site") {
|
|
38011
|
+
return c.json({ error: "forbidden", reason: "cross-origin request rejected" }, 403);
|
|
38012
|
+
}
|
|
38013
|
+
const origin = c.req.header("origin");
|
|
38014
|
+
if (origin !== void 0 && origin !== "" && !isLoopbackOrigin(origin)) {
|
|
38015
|
+
return c.json({ error: "forbidden", reason: "untrusted origin" }, 403);
|
|
38016
|
+
}
|
|
38017
|
+
const session = c.req.header("x-honeycomb-session");
|
|
38018
|
+
if (session === void 0 || session.trim() === "") {
|
|
38019
|
+
return c.json({ error: "forbidden", reason: "missing dashboard session header" }, 403);
|
|
38020
|
+
}
|
|
38021
|
+
return null;
|
|
38022
|
+
}
|
|
38023
|
+
async function readEnabled(c) {
|
|
38024
|
+
try {
|
|
38025
|
+
const body = await c.req.json();
|
|
38026
|
+
if (typeof body === "object" && body !== null) {
|
|
38027
|
+
const v = body.enabled;
|
|
38028
|
+
if (typeof v === "boolean")
|
|
38029
|
+
return v;
|
|
38030
|
+
if (v === "true" || v === 1)
|
|
38031
|
+
return true;
|
|
38032
|
+
if (v === "false" || v === 0)
|
|
38033
|
+
return false;
|
|
38034
|
+
}
|
|
38035
|
+
return null;
|
|
38036
|
+
} catch {
|
|
38037
|
+
return null;
|
|
38038
|
+
}
|
|
38039
|
+
}
|
|
38040
|
+
function defaultRemoveCredentials() {
|
|
38041
|
+
for (const path4 of [credentialsPath(), legacyCredentialsPath()]) {
|
|
38042
|
+
try {
|
|
38043
|
+
rmSync5(path4, { force: true });
|
|
38044
|
+
} catch {
|
|
38045
|
+
}
|
|
38046
|
+
}
|
|
38047
|
+
}
|
|
38048
|
+
function defaultShutdown() {
|
|
38049
|
+
try {
|
|
38050
|
+
process.kill(process.pid, "SIGTERM");
|
|
38051
|
+
} catch {
|
|
38052
|
+
}
|
|
38053
|
+
}
|
|
38054
|
+
function defaultSpawnRestart() {
|
|
38055
|
+
const entry = process.argv[1];
|
|
38056
|
+
if (entry === void 0 || entry === "")
|
|
38057
|
+
return;
|
|
38058
|
+
const helper = resolve5(dirname12(entry), "restart-helper.js");
|
|
38059
|
+
const child = spawn4(process.execPath, [helper], {
|
|
38060
|
+
detached: true,
|
|
38061
|
+
stdio: "ignore",
|
|
38062
|
+
env: { ...process.env, HONEYCOMB_RESTART_ENTRY: entry, HONEYCOMB_RESTART_PORT: String(DAEMON_PORT) }
|
|
38063
|
+
});
|
|
38064
|
+
child.unref();
|
|
38065
|
+
}
|
|
38066
|
+
function defaultUninstall() {
|
|
38067
|
+
const harnesses = [...detectInstalledHarnesses()];
|
|
38068
|
+
return {
|
|
38069
|
+
ok: true,
|
|
38070
|
+
harnesses,
|
|
38071
|
+
removed: false,
|
|
38072
|
+
command: "honeycomb uninstall",
|
|
38073
|
+
note: "Run `honeycomb uninstall` in your terminal to remove Honeycomb's hooks from your coding assistants. It reverses only Honeycomb's changes; your DeepLake login is left intact (use Log out for that)."
|
|
38074
|
+
};
|
|
38075
|
+
}
|
|
38076
|
+
function mountActionsGroup(group, mode, options) {
|
|
38077
|
+
const embed = options.embed;
|
|
38078
|
+
const store = options.store;
|
|
38079
|
+
const removeCredentials = options.removeCredentials ?? defaultRemoveCredentials;
|
|
38080
|
+
const shutdown = options.shutdown ?? defaultShutdown;
|
|
38081
|
+
const spawnRestart = options.spawnRestart ?? defaultSpawnRestart;
|
|
38082
|
+
const uninstall = options.uninstall ?? defaultUninstall;
|
|
38083
|
+
const settingsScope = localDefaultScopeResolver(mode, options.defaultScope);
|
|
38084
|
+
group.post("/logout", (c) => {
|
|
38085
|
+
const denied = actionGuard(c, mode);
|
|
38086
|
+
if (denied)
|
|
38087
|
+
return denied;
|
|
38088
|
+
removeCredentials();
|
|
38089
|
+
return c.json({ ok: true });
|
|
38090
|
+
});
|
|
38091
|
+
group.post("/embeddings", async (c) => {
|
|
38092
|
+
const denied = actionGuard(c, mode);
|
|
38093
|
+
if (denied)
|
|
38094
|
+
return denied;
|
|
38095
|
+
const enabled = await readEnabled(c);
|
|
38096
|
+
if (enabled === null) {
|
|
38097
|
+
return c.json({ error: "bad_request", reason: "body must carry { enabled: boolean }" }, 400);
|
|
38098
|
+
}
|
|
38099
|
+
if (store !== void 0) {
|
|
38100
|
+
const sc = settingsScope.resolve(c);
|
|
38101
|
+
if (sc !== null) {
|
|
38102
|
+
try {
|
|
38103
|
+
await store.setSetting(EMBEDDINGS_ENABLED_KEY, enabled, sc);
|
|
38104
|
+
} catch {
|
|
38105
|
+
}
|
|
38106
|
+
}
|
|
38107
|
+
}
|
|
38108
|
+
await embed.setEnabled(enabled);
|
|
38109
|
+
return c.json({ ok: true, enabled });
|
|
38110
|
+
});
|
|
38111
|
+
group.post("/restart", (c) => {
|
|
38112
|
+
const denied = actionGuard(c, mode);
|
|
38113
|
+
if (denied)
|
|
38114
|
+
return denied;
|
|
38115
|
+
spawnRestart();
|
|
38116
|
+
setTimeout(() => shutdown(), RESTART_SHUTDOWN_DELAY_MS);
|
|
38117
|
+
return c.json({ ok: true, restarting: true });
|
|
38118
|
+
});
|
|
38119
|
+
group.post("/uninstall", (c) => {
|
|
38120
|
+
const denied = actionGuard(c, mode);
|
|
38121
|
+
if (denied)
|
|
38122
|
+
return denied;
|
|
38123
|
+
return c.json(uninstall());
|
|
38124
|
+
});
|
|
38125
|
+
}
|
|
38126
|
+
function mountActionsApi(daemon, options) {
|
|
38127
|
+
const group = daemon.group(ACTIONS_GROUP);
|
|
38128
|
+
if (group === void 0)
|
|
38129
|
+
return;
|
|
38130
|
+
mountActionsGroup(group, daemon.config.mode, options);
|
|
38131
|
+
}
|
|
38132
|
+
|
|
37345
38133
|
// dist/src/daemon/runtime/dashboard/harness-api.js
|
|
37346
38134
|
var HARNESS_GROUP = "/api/diagnostics";
|
|
37347
38135
|
var HARNESS_PATH = "/harnesses";
|
|
@@ -37871,25 +38659,25 @@ async function tableAbsent(probe, table) {
|
|
|
37871
38659
|
}
|
|
37872
38660
|
|
|
37873
38661
|
// dist/src/daemon/runtime/dashboard/asset-install-target.js
|
|
37874
|
-
import { existsSync as
|
|
37875
|
-
import { homedir as
|
|
37876
|
-
import { join as
|
|
37877
|
-
var SKILLS_SUBDIR =
|
|
37878
|
-
var AGENTS_SUBDIR =
|
|
38662
|
+
import { existsSync as existsSync13, mkdirSync as mkdirSync14, readFileSync as readFileSync16, rmSync as rmSync6, writeFileSync as writeFileSync12 } from "node:fs";
|
|
38663
|
+
import { homedir as homedir17 } from "node:os";
|
|
38664
|
+
import { join as join21 } from "node:path";
|
|
38665
|
+
var SKILLS_SUBDIR = join21(".claude", "skills");
|
|
38666
|
+
var AGENTS_SUBDIR = join21(".claude", "agents");
|
|
37879
38667
|
var SKILL_FILE3 = "SKILL.md";
|
|
37880
38668
|
function createFsAssetInstallTarget(dirs = {}) {
|
|
37881
38669
|
const projectDir = dirs.projectDir ?? process.cwd();
|
|
37882
|
-
const globalDir = dirs.globalDir ??
|
|
38670
|
+
const globalDir = dirs.globalDir ?? homedir17();
|
|
37883
38671
|
const rootFor = (install) => install === "global" ? globalDir : projectDir;
|
|
37884
38672
|
const pathFor = (assetType, install, name) => {
|
|
37885
38673
|
const root = rootFor(install);
|
|
37886
38674
|
const segment = sanitizeSegment3(name);
|
|
37887
38675
|
if (assetType === "agent") {
|
|
37888
|
-
const dir2 =
|
|
37889
|
-
return { dir: dir2, file:
|
|
38676
|
+
const dir2 = join21(root, AGENTS_SUBDIR);
|
|
38677
|
+
return { dir: dir2, file: join21(dir2, `${segment}.md`) };
|
|
37890
38678
|
}
|
|
37891
|
-
const dir =
|
|
37892
|
-
return { dir, file:
|
|
38679
|
+
const dir = join21(root, SKILLS_SUBDIR, segment);
|
|
38680
|
+
return { dir, file: join21(dir, SKILL_FILE3) };
|
|
37893
38681
|
};
|
|
37894
38682
|
return {
|
|
37895
38683
|
async write(assetType, install, name, body) {
|
|
@@ -37905,7 +38693,7 @@ function createFsAssetInstallTarget(dirs = {}) {
|
|
|
37905
38693
|
async read(assetType, install, name) {
|
|
37906
38694
|
try {
|
|
37907
38695
|
const { file: file2 } = pathFor(assetType, install, name);
|
|
37908
|
-
if (!
|
|
38696
|
+
if (!existsSync13(file2))
|
|
37909
38697
|
return null;
|
|
37910
38698
|
return readFileSync16(file2, "utf-8");
|
|
37911
38699
|
} catch {
|
|
@@ -37916,14 +38704,14 @@ function createFsAssetInstallTarget(dirs = {}) {
|
|
|
37916
38704
|
try {
|
|
37917
38705
|
const { dir, file: file2 } = pathFor(assetType, install, name);
|
|
37918
38706
|
if (assetType === "agent") {
|
|
37919
|
-
if (!
|
|
38707
|
+
if (!existsSync13(file2))
|
|
37920
38708
|
return false;
|
|
37921
|
-
|
|
38709
|
+
rmSync6(file2, { force: true });
|
|
37922
38710
|
return true;
|
|
37923
38711
|
}
|
|
37924
|
-
if (!
|
|
38712
|
+
if (!existsSync13(dir))
|
|
37925
38713
|
return false;
|
|
37926
|
-
|
|
38714
|
+
rmSync6(dir, { recursive: true, force: true });
|
|
37927
38715
|
return true;
|
|
37928
38716
|
} catch {
|
|
37929
38717
|
return false;
|
|
@@ -37931,7 +38719,7 @@ function createFsAssetInstallTarget(dirs = {}) {
|
|
|
37931
38719
|
},
|
|
37932
38720
|
exists(assetType, install, name) {
|
|
37933
38721
|
try {
|
|
37934
|
-
return
|
|
38722
|
+
return existsSync13(pathFor(assetType, install, name).file);
|
|
37935
38723
|
} catch {
|
|
37936
38724
|
return false;
|
|
37937
38725
|
}
|
|
@@ -38309,67 +39097,9 @@ function pickAssetType(value) {
|
|
|
38309
39097
|
return typeof value === "string" && SYNCED_ASSET_TYPES.includes(value) ? value : null;
|
|
38310
39098
|
}
|
|
38311
39099
|
|
|
38312
|
-
// dist/src/daemon/runtime/dashboard/harness-detect.js
|
|
38313
|
-
import { existsSync as existsSync13 } from "node:fs";
|
|
38314
|
-
import { homedir as homedir16 } from "node:os";
|
|
38315
|
-
import { join as join21 } from "node:path";
|
|
38316
|
-
var HARNESS_MARKERS = [
|
|
38317
|
-
{
|
|
38318
|
-
name: "claude-code",
|
|
38319
|
-
// src/connectors/claude-code.ts: configPath() = ~/.claude/settings.json; pluginRoot = ~/.claude/plugins/honeycomb.
|
|
38320
|
-
paths: (h) => [join21(h, ".claude", "settings.json"), join21(h, ".claude", "plugins", "honeycomb")]
|
|
38321
|
-
},
|
|
38322
|
-
{
|
|
38323
|
-
name: "cursor",
|
|
38324
|
-
// src/connectors/cursor.ts: configPath() = ~/.cursor/hooks.json; pluginRoot = ~/.cursor/honeycomb.
|
|
38325
|
-
paths: (h) => [join21(h, ".cursor", "hooks.json"), join21(h, ".cursor", "honeycomb")]
|
|
38326
|
-
},
|
|
38327
|
-
{
|
|
38328
|
-
name: "codex",
|
|
38329
|
-
// hivemind-v1/src/cli/install-codex.ts: HOOKS_PATH = ~/.codex/hooks.json; PLUGIN_DIR = ~/.codex/hivemind.
|
|
38330
|
-
paths: (h) => [join21(h, ".codex", "hooks.json"), join21(h, ".codex", "hivemind")]
|
|
38331
|
-
},
|
|
38332
|
-
{
|
|
38333
|
-
name: "hermes",
|
|
38334
|
-
// hivemind-v1/src/cli/install-hermes.ts: CONFIG_PATH = ~/.hermes/config.yaml; HIVEMIND_DIR = ~/.hermes/hivemind.
|
|
38335
|
-
paths: (h) => [join21(h, ".hermes", "config.yaml"), join21(h, ".hermes", "hivemind")]
|
|
38336
|
-
},
|
|
38337
|
-
{
|
|
38338
|
-
name: "pi",
|
|
38339
|
-
// hivemind-v1/src/cli/install-pi.ts: AGENTS_MD = ~/.pi/agent/AGENTS.md; EXTENSION_PATH = ~/.pi/agent/extensions/hivemind.ts.
|
|
38340
|
-
paths: (h) => [
|
|
38341
|
-
join21(h, ".pi", "agent", "extensions", "hivemind.ts"),
|
|
38342
|
-
join21(h, ".pi", "agent", "AGENTS.md")
|
|
38343
|
-
]
|
|
38344
|
-
},
|
|
38345
|
-
{
|
|
38346
|
-
name: "openclaw",
|
|
38347
|
-
// hivemind-v1/src/cli/install-openclaw.ts: PLUGIN_DIR = ~/.openclaw/extensions/hivemind.
|
|
38348
|
-
paths: (h) => [join21(h, ".openclaw", "extensions", "hivemind")]
|
|
38349
|
-
}
|
|
38350
|
-
];
|
|
38351
|
-
function markerExists(path4) {
|
|
38352
|
-
try {
|
|
38353
|
-
return existsSync13(path4);
|
|
38354
|
-
} catch {
|
|
38355
|
-
return false;
|
|
38356
|
-
}
|
|
38357
|
-
}
|
|
38358
|
-
function detectInstalledHarnesses(homeDir = homedir16(), _cwd = process.cwd()) {
|
|
38359
|
-
const canonical = new Set(CANONICAL_HARNESS_IDS);
|
|
38360
|
-
const installed = /* @__PURE__ */ new Set();
|
|
38361
|
-
for (const marker of HARNESS_MARKERS) {
|
|
38362
|
-
if (!canonical.has(marker.name))
|
|
38363
|
-
continue;
|
|
38364
|
-
if (marker.paths(homeDir).some(markerExists))
|
|
38365
|
-
installed.add(marker.name);
|
|
38366
|
-
}
|
|
38367
|
-
return installed;
|
|
38368
|
-
}
|
|
38369
|
-
|
|
38370
39100
|
// dist/src/daemon/runtime/dashboard/web-assets.js
|
|
38371
39101
|
import { existsSync as existsSync14, readFileSync as readFileSync17 } from "node:fs";
|
|
38372
|
-
import { dirname as
|
|
39102
|
+
import { dirname as dirname13, join as join22 } from "node:path";
|
|
38373
39103
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
38374
39104
|
var CSS_FILES = ["tokens/fonts.css", "tokens/colors.css", "tokens/typography.css", "tokens/spacing.css", "tokens/base.css"];
|
|
38375
39105
|
var LOGO_FILE = "logos/honeycomb-memory-cluster.svg";
|
|
@@ -38394,7 +39124,7 @@ var DASHBOARD_APP_BUNDLE = "dashboard-app.js";
|
|
|
38394
39124
|
function resolveAssetsDir(startUrl = import.meta.url) {
|
|
38395
39125
|
let dir;
|
|
38396
39126
|
try {
|
|
38397
|
-
dir =
|
|
39127
|
+
dir = dirname13(fileURLToPath2(startUrl));
|
|
38398
39128
|
} catch {
|
|
38399
39129
|
return null;
|
|
38400
39130
|
}
|
|
@@ -38402,7 +39132,7 @@ function resolveAssetsDir(startUrl = import.meta.url) {
|
|
|
38402
39132
|
const candidate = join22(dir, "assets");
|
|
38403
39133
|
if (existsSync14(join22(candidate, "styles.css")))
|
|
38404
39134
|
return candidate;
|
|
38405
|
-
const parent =
|
|
39135
|
+
const parent = dirname13(dir);
|
|
38406
39136
|
if (parent === dir)
|
|
38407
39137
|
break;
|
|
38408
39138
|
dir = parent;
|
|
@@ -38411,7 +39141,7 @@ function resolveAssetsDir(startUrl = import.meta.url) {
|
|
|
38411
39141
|
}
|
|
38412
39142
|
function resolveBundleDir(startUrl = import.meta.url) {
|
|
38413
39143
|
try {
|
|
38414
|
-
return
|
|
39144
|
+
return dirname13(fileURLToPath2(startUrl));
|
|
38415
39145
|
} catch {
|
|
38416
39146
|
return null;
|
|
38417
39147
|
}
|
|
@@ -38523,24 +39253,27 @@ function mountDashboardHost(daemon, options = {}) {
|
|
|
38523
39253
|
if (root === void 0)
|
|
38524
39254
|
return;
|
|
38525
39255
|
const assets = options.assets ?? createWebAssets();
|
|
38526
|
-
root.get(DASHBOARD_HOST_PATH, (c) =>
|
|
39256
|
+
root.get(DASHBOARD_HOST_PATH, (c) => {
|
|
39257
|
+
c.header("cache-control", "no-cache");
|
|
39258
|
+
return c.html(renderShell());
|
|
39259
|
+
});
|
|
38527
39260
|
root.get(DASHBOARD_APP_PATH, (c) => {
|
|
38528
39261
|
const asset = assets.appJs();
|
|
38529
39262
|
if (asset === null)
|
|
38530
39263
|
return c.text("dashboard bundle not built", 404);
|
|
38531
|
-
return c.body(asset.body, 200, { "content-type": asset.contentType });
|
|
39264
|
+
return c.body(asset.body, 200, { "content-type": asset.contentType, "cache-control": "no-cache" });
|
|
38532
39265
|
});
|
|
38533
39266
|
root.get(DASHBOARD_CSS_PATH, (c) => {
|
|
38534
39267
|
const asset = assets.css();
|
|
38535
39268
|
if (asset === null)
|
|
38536
39269
|
return c.text("dashboard styles unavailable", 404);
|
|
38537
|
-
return c.body(asset.body, 200, { "content-type": asset.contentType });
|
|
39270
|
+
return c.body(asset.body, 200, { "content-type": asset.contentType, "cache-control": "no-cache" });
|
|
38538
39271
|
});
|
|
38539
39272
|
root.get(DASHBOARD_LOGO_PATH, (c) => {
|
|
38540
39273
|
const asset = assets.logo();
|
|
38541
39274
|
if (asset === null)
|
|
38542
39275
|
return c.text("dashboard logo unavailable", 404);
|
|
38543
|
-
return c.body(asset.body, 200, { "content-type": asset.contentType });
|
|
39276
|
+
return c.body(asset.body, 200, { "content-type": asset.contentType, "cache-control": "no-cache" });
|
|
38544
39277
|
});
|
|
38545
39278
|
root.get(DASHBOARD_FONT_PATH, (c) => {
|
|
38546
39279
|
const asset = assets.font(c.req.param("name"));
|
|
@@ -38589,8 +39322,8 @@ function mountSetupLogin(daemon, options = {}) {
|
|
|
38589
39322
|
};
|
|
38590
39323
|
let rejectGrant = () => {
|
|
38591
39324
|
};
|
|
38592
|
-
const grantReady = new Promise((
|
|
38593
|
-
resolveGrant =
|
|
39325
|
+
const grantReady = new Promise((resolve7, reject) => {
|
|
39326
|
+
resolveGrant = resolve7;
|
|
38594
39327
|
rejectGrant = reject;
|
|
38595
39328
|
});
|
|
38596
39329
|
const deps = {
|
|
@@ -38621,7 +39354,7 @@ function mountSetupLogin(daemon, options = {}) {
|
|
|
38621
39354
|
|
|
38622
39355
|
// dist/src/daemon/runtime/dashboard/setup-state.js
|
|
38623
39356
|
import { existsSync as existsSync15 } from "node:fs";
|
|
38624
|
-
import { homedir as
|
|
39357
|
+
import { homedir as homedir18 } from "node:os";
|
|
38625
39358
|
import { join as join23 } from "node:path";
|
|
38626
39359
|
var SETUP_STATE_PATH = "/setup/state";
|
|
38627
39360
|
var SETUP_STATE_GROUP = "/";
|
|
@@ -38644,7 +39377,7 @@ function derivePriorTool(recorded, hivemindDirPresent) {
|
|
|
38644
39377
|
return hivemindDirPresent ? { hivemind: "present" } : recorded;
|
|
38645
39378
|
}
|
|
38646
39379
|
function resolveSetupState(deps = {}) {
|
|
38647
|
-
const home = deps.homeDir ??
|
|
39380
|
+
const home = deps.homeDir ?? homedir18();
|
|
38648
39381
|
const env = deps.env ?? process.env;
|
|
38649
39382
|
const onboarding = loadOnboarding(deps.onboardingDir);
|
|
38650
39383
|
const legacyCredentialsDir = deps.legacyCredentialsDir ?? join23(home, LEGACY_CREDENTIALS_DIR_NAME);
|
|
@@ -38679,8 +39412,8 @@ function mountSetupStateApi(daemon, deps = {}) {
|
|
|
38679
39412
|
|
|
38680
39413
|
// dist/src/daemon/runtime/onboarding/hivemind-uninstall.js
|
|
38681
39414
|
import { execFileSync as execFileSync5 } from "node:child_process";
|
|
38682
|
-
import { cpSync, existsSync as existsSync16, rmSync as
|
|
38683
|
-
import { homedir as
|
|
39415
|
+
import { cpSync, existsSync as existsSync16, rmSync as rmSync7 } from "node:fs";
|
|
39416
|
+
import { homedir as homedir19 } from "node:os";
|
|
38684
39417
|
import { join as join24 } from "node:path";
|
|
38685
39418
|
var HIVEMIND_DIR_NAME2 = ".hivemind";
|
|
38686
39419
|
var HIVEMIND_NPM_PACKAGE = "@deeplake/hivemind";
|
|
@@ -38702,7 +39435,7 @@ function hivemindBackupPath(home, iso) {
|
|
|
38702
39435
|
return join24(home, `${HIVEMIND_BACKUP_PREFIX}${safe}`);
|
|
38703
39436
|
}
|
|
38704
39437
|
function backupAndUninstallHivemind(deps = {}) {
|
|
38705
|
-
const home = deps.homeDir ??
|
|
39438
|
+
const home = deps.homeDir ?? homedir19();
|
|
38706
39439
|
const npmRemove = deps.npmRemove ?? defaultNpmGlobalRemover;
|
|
38707
39440
|
const dir = hivemindDirPath(home);
|
|
38708
39441
|
let npmRemoved = false;
|
|
@@ -38718,7 +39451,7 @@ function backupAndUninstallHivemind(deps = {}) {
|
|
|
38718
39451
|
const backupPath = hivemindBackupPath(home, iso);
|
|
38719
39452
|
cpSync(dir, backupPath, { recursive: true });
|
|
38720
39453
|
try {
|
|
38721
|
-
|
|
39454
|
+
rmSync7(dir, { recursive: true, force: true });
|
|
38722
39455
|
return { removed: true, backupPath, npmRemoved };
|
|
38723
39456
|
} catch {
|
|
38724
39457
|
return { removed: false, backupPath, npmRemoved };
|
|
@@ -38727,9 +39460,9 @@ function backupAndUninstallHivemind(deps = {}) {
|
|
|
38727
39460
|
function restoreHivemindBackup(backupPath, deps = {}) {
|
|
38728
39461
|
if (backupPath.length === 0 || !existsSync16(backupPath))
|
|
38729
39462
|
return false;
|
|
38730
|
-
const home = deps.homeDir ??
|
|
39463
|
+
const home = deps.homeDir ?? homedir19();
|
|
38731
39464
|
const dir = hivemindDirPath(home);
|
|
38732
|
-
|
|
39465
|
+
rmSync7(dir, { recursive: true, force: true });
|
|
38733
39466
|
cpSync(backupPath, dir, { recursive: true });
|
|
38734
39467
|
return true;
|
|
38735
39468
|
}
|
|
@@ -39549,8 +40282,8 @@ function resolveProjectsScope(c, defaultScope) {
|
|
|
39549
40282
|
|
|
39550
40283
|
// dist/src/daemon/runtime/projects/onboarding-api.js
|
|
39551
40284
|
import { existsSync as existsSync17, readdirSync as readdirSync3, realpathSync, statSync as statSync2 } from "node:fs";
|
|
39552
|
-
import { homedir as
|
|
39553
|
-
import { isAbsolute as isAbsolute2, join as join25, resolve as
|
|
40285
|
+
import { homedir as homedir20 } from "node:os";
|
|
40286
|
+
import { isAbsolute as isAbsolute2, join as join25, resolve as resolve6, sep as sep3 } from "node:path";
|
|
39554
40287
|
var ONBOARDING_GROUP = "/api/diagnostics";
|
|
39555
40288
|
var FS_BROWSE_PATH = "/fs/browse";
|
|
39556
40289
|
var PROJECTS_BIND_PATH = "/projects/bind";
|
|
@@ -39578,19 +40311,19 @@ function suggestProjectId(absPath, readRemote) {
|
|
|
39578
40311
|
return repo;
|
|
39579
40312
|
}
|
|
39580
40313
|
}
|
|
39581
|
-
const segs =
|
|
40314
|
+
const segs = resolve6(absPath).split(sep3).filter((s) => s.length > 0);
|
|
39582
40315
|
const base = segs[segs.length - 1];
|
|
39583
40316
|
return base ?? "";
|
|
39584
40317
|
}
|
|
39585
40318
|
function canonicalize(absPath) {
|
|
39586
|
-
let head =
|
|
40319
|
+
let head = resolve6(absPath);
|
|
39587
40320
|
const tail = [];
|
|
39588
40321
|
for (; ; ) {
|
|
39589
40322
|
try {
|
|
39590
40323
|
const real = realpathSync(head);
|
|
39591
40324
|
return stripTrailingSep(tail.length > 0 ? join25(real, ...tail.reverse()) : real);
|
|
39592
40325
|
} catch {
|
|
39593
|
-
const parent =
|
|
40326
|
+
const parent = resolve6(head, "..");
|
|
39594
40327
|
if (parent === head)
|
|
39595
40328
|
return stripTrailingSep(head);
|
|
39596
40329
|
const segmentStart = parent.endsWith(sep3) ? parent.length : parent.length + sep3.length;
|
|
@@ -39617,7 +40350,7 @@ function parentWithinRoot(dir, root) {
|
|
|
39617
40350
|
const normalizedRoot = root;
|
|
39618
40351
|
if (dir === normalizedRoot)
|
|
39619
40352
|
return null;
|
|
39620
|
-
const parent = canonicalize(
|
|
40353
|
+
const parent = canonicalize(resolve6(dir, ".."));
|
|
39621
40354
|
return parent === normalizedRoot || parent.startsWith(normalizedRoot + sep3) ? parent : normalizedRoot;
|
|
39622
40355
|
}
|
|
39623
40356
|
function listChildDirs(dir) {
|
|
@@ -39655,7 +40388,7 @@ function mountOnboardingApi(daemon, options) {
|
|
|
39655
40388
|
if (group === void 0)
|
|
39656
40389
|
return;
|
|
39657
40390
|
const mode = daemon.config.mode;
|
|
39658
|
-
const root = canonicalize(options.browseRoot ??
|
|
40391
|
+
const root = canonicalize(options.browseRoot ?? homedir20());
|
|
39659
40392
|
const readRemote = options.readRemote ?? defaultGitRemoteReader;
|
|
39660
40393
|
const notLocal = () => mode !== "local";
|
|
39661
40394
|
group.get(FS_BROWSE_PATH, (c) => {
|
|
@@ -39747,7 +40480,7 @@ function resolveBindPath(path4) {
|
|
|
39747
40480
|
const trimmed = path4.trim();
|
|
39748
40481
|
if (trimmed.length === 0 || !isAbsolute2(trimmed))
|
|
39749
40482
|
return null;
|
|
39750
|
-
return
|
|
40483
|
+
return resolve6(trimmed);
|
|
39751
40484
|
}
|
|
39752
40485
|
function rejectBind(path4, reason) {
|
|
39753
40486
|
return { bound: false, path: path4, projectId: "", error: reason };
|
|
@@ -39776,9 +40509,9 @@ function remoteFor(absPath, readRemote) {
|
|
|
39776
40509
|
return raw2 !== null ? canonicalizeRemote(raw2) : "";
|
|
39777
40510
|
}
|
|
39778
40511
|
function removeBinding(absPath, options) {
|
|
39779
|
-
const normalized = stripTrailingSep(
|
|
40512
|
+
const normalized = stripTrailingSep(resolve6(absPath));
|
|
39780
40513
|
const loaded = loadProjectsCache(options.projectsDir);
|
|
39781
|
-
const kept = loaded.bindings.filter((b) => stripTrailingSep(
|
|
40514
|
+
const kept = loaded.bindings.filter((b) => stripTrailingSep(resolve6(b.path)) !== normalized);
|
|
39782
40515
|
if (kept.length === loaded.bindings.length) {
|
|
39783
40516
|
return { unbound: false, path: normalized };
|
|
39784
40517
|
}
|
|
@@ -41384,7 +42117,7 @@ function recordKey(record2) {
|
|
|
41384
42117
|
// dist/src/daemon/runtime/notifications/api.js
|
|
41385
42118
|
var NOTIFICATIONS_GROUP = "/api/diagnostics";
|
|
41386
42119
|
var NOTIFICATIONS_PATH = "/notifications";
|
|
41387
|
-
var
|
|
42120
|
+
var headerScopeResolver2 = {
|
|
41388
42121
|
resolve(c) {
|
|
41389
42122
|
const org = c.req.header("x-honeycomb-org");
|
|
41390
42123
|
if (org === void 0 || org.length === 0)
|
|
@@ -41428,7 +42161,7 @@ function mountNotificationsApi(daemon, options) {
|
|
|
41428
42161
|
if (group === void 0)
|
|
41429
42162
|
return;
|
|
41430
42163
|
const table = options.table ?? "notifications";
|
|
41431
|
-
const scopeResolver = options.scope ??
|
|
42164
|
+
const scopeResolver = options.scope ?? headerScopeResolver2;
|
|
41432
42165
|
group.get(NOTIFICATIONS_PATH, async (c) => {
|
|
41433
42166
|
const scope = scopeResolver.resolve(c);
|
|
41434
42167
|
if (scope === null) {
|
|
@@ -41614,6 +42347,8 @@ var DEFAULT_TRAVERSAL_MIN_EDGE_WEIGHT = 0.3;
|
|
|
41614
42347
|
var DEFAULT_TRAVERSAL_TIMEOUT_MS = 500;
|
|
41615
42348
|
var DEFAULT_RERANKER = "none";
|
|
41616
42349
|
var DEFAULT_RERANKER_TIMEOUT_MS = 300;
|
|
42350
|
+
var DEFAULT_RERANKER_PROVIDER_TIMEOUT_MS = 1e3;
|
|
42351
|
+
var DEFAULT_RERANKER_COHERE_MODEL = "rerank-v3.5";
|
|
41617
42352
|
var DEFAULT_RERANKER_WINDOW = 50;
|
|
41618
42353
|
var DEFAULT_DEDUP_ENABLED = true;
|
|
41619
42354
|
var DEFAULT_DEDUP_SIMILARITY_THRESHOLD = 0.9;
|
|
@@ -41632,7 +42367,7 @@ var DEFAULT_RESOLUTION_BOOST = 1.25;
|
|
|
41632
42367
|
var DEFAULT_REHEARSAL_BOOST = 1.1;
|
|
41633
42368
|
var DEFAULT_REHEARSAL_WINDOW_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
41634
42369
|
var DEFAULT_MIN_INJECTION_SCORE = 0.6;
|
|
41635
|
-
var RERANKER_STRATEGIES = Object.freeze(["embedding-cosine", "llm", "none"]);
|
|
42370
|
+
var RERANKER_STRATEGIES = Object.freeze(["embedding-cosine", "llm", "cohere", "none"]);
|
|
41636
42371
|
var BoolFlag3 = external_exports.preprocess((raw2) => {
|
|
41637
42372
|
if (typeof raw2 === "boolean")
|
|
41638
42373
|
return raw2;
|
|
@@ -41687,12 +42422,26 @@ var TraversalConfigSchema = external_exports.object({
|
|
|
41687
42422
|
timeoutMs: ClampedInt4(DEFAULT_TRAVERSAL_TIMEOUT_MS, 1).default(DEFAULT_TRAVERSAL_TIMEOUT_MS)
|
|
41688
42423
|
});
|
|
41689
42424
|
var RerankerConfigSchema = external_exports.object({
|
|
41690
|
-
/** The reranker strategy (D-4). */
|
|
42425
|
+
/** The reranker strategy (D-4 + PRD-063c). */
|
|
41691
42426
|
strategy: external_exports.enum(RERANKER_STRATEGIES).default(DEFAULT_RERANKER),
|
|
41692
|
-
/** Reranker timeout in ms; on timeout keep the original order (d-AC-2 / b-AC-2). */
|
|
42427
|
+
/** Reranker timeout in ms; on timeout keep the original order (d-AC-2 / b-AC-2). LOCAL-cosine budget. */
|
|
41693
42428
|
timeoutMs: ClampedInt4(DEFAULT_RERANKER_TIMEOUT_MS, 1).default(DEFAULT_RERANKER_TIMEOUT_MS),
|
|
42429
|
+
/**
|
|
42430
|
+
* The PROVIDER-rerank timeout in ms (PRD-063c / c-AC-3): the budget for the `cohere` outbound
|
|
42431
|
+
* Portkey round-trip, larger than the local-cosine {@link timeoutMs} because it crosses the
|
|
42432
|
+
* network. A `cohere` call that exceeds it FAILS SOFT to the RRF order. Defaults to
|
|
42433
|
+
* {@link DEFAULT_RERANKER_PROVIDER_TIMEOUT_MS} (1000ms); the local-cosine path never reads it.
|
|
42434
|
+
*/
|
|
42435
|
+
providerTimeoutMs: ClampedInt4(DEFAULT_RERANKER_PROVIDER_TIMEOUT_MS, 1).default(DEFAULT_RERANKER_PROVIDER_TIMEOUT_MS),
|
|
41694
42436
|
/** Rerank window N: how many fused top-N candidates to re-score (PRD-047b). */
|
|
41695
|
-
window: ClampedInt4(DEFAULT_RERANKER_WINDOW, 1).default(DEFAULT_RERANKER_WINDOW)
|
|
42437
|
+
window: ClampedInt4(DEFAULT_RERANKER_WINDOW, 1).default(DEFAULT_RERANKER_WINDOW),
|
|
42438
|
+
/**
|
|
42439
|
+
* The Cohere rerank `model` id sent to Portkey when the strategy is `cohere` (PRD-063c / c-D-1).
|
|
42440
|
+
* Defaults to {@link DEFAULT_RERANKER_COHERE_MODEL}; the operator may override it (or configure
|
|
42441
|
+
* the model inside Portkey). A non-string env value falls back to the default. Only the `cohere`
|
|
42442
|
+
* strategy reads it.
|
|
42443
|
+
*/
|
|
42444
|
+
cohereModel: external_exports.string().min(1).catch(DEFAULT_RERANKER_COHERE_MODEL).default(DEFAULT_RERANKER_COHERE_MODEL)
|
|
41696
42445
|
});
|
|
41697
42446
|
var DedupConfigSchema = external_exports.object({
|
|
41698
42447
|
/** Whether semantic near-duplicate dedup runs; ON by default (PRD-047c / c-AC-3). */
|
|
@@ -41792,7 +42541,9 @@ function envRecallConfigProvider(env = process.env) {
|
|
|
41792
42541
|
reranker: {
|
|
41793
42542
|
strategy: env.HONEYCOMB_RECALL_RERANKER,
|
|
41794
42543
|
timeoutMs: env.HONEYCOMB_RECALL_RERANKER_TIMEOUT_MS,
|
|
41795
|
-
|
|
42544
|
+
providerTimeoutMs: env.HONEYCOMB_RECALL_RERANKER_PROVIDER_TIMEOUT_MS,
|
|
42545
|
+
window: env.HONEYCOMB_RECALL_RERANKER_WINDOW,
|
|
42546
|
+
cohereModel: env.HONEYCOMB_RECALL_RERANKER_COHERE_MODEL
|
|
41796
42547
|
},
|
|
41797
42548
|
dampening: {
|
|
41798
42549
|
gravity: env.HONEYCOMB_RECALL_DAMPENING_GRAVITY,
|
|
@@ -41861,10 +42612,10 @@ var Semaphore = class {
|
|
|
41861
42612
|
this.held += 1;
|
|
41862
42613
|
return Promise.resolve();
|
|
41863
42614
|
}
|
|
41864
|
-
return new Promise((
|
|
42615
|
+
return new Promise((resolve7) => {
|
|
41865
42616
|
this.waiters.push(() => {
|
|
41866
42617
|
this.held += 1;
|
|
41867
|
-
|
|
42618
|
+
resolve7();
|
|
41868
42619
|
});
|
|
41869
42620
|
});
|
|
41870
42621
|
}
|
|
@@ -42367,9 +43118,16 @@ async function fetchCandidateEmbeddings(candidates, request, deps) {
|
|
|
42367
43118
|
}
|
|
42368
43119
|
async function rerankHits(hits, queryVector, config2, request, deps) {
|
|
42369
43120
|
const rrfOrder = [...hits];
|
|
43121
|
+
if (hits.length === 0)
|
|
43122
|
+
return rrfOrder;
|
|
43123
|
+
if (config2.strategy === "cohere") {
|
|
43124
|
+
if (deps.cohereRerank === void 0)
|
|
43125
|
+
return rrfOrder;
|
|
43126
|
+
return rerankWithCohere(rrfOrder, config2, request, deps, deps.cohereRerank);
|
|
43127
|
+
}
|
|
42370
43128
|
if (config2.strategy !== "embedding-cosine")
|
|
42371
43129
|
return rrfOrder;
|
|
42372
|
-
if (
|
|
43130
|
+
if (queryVector === null)
|
|
42373
43131
|
return rrfOrder;
|
|
42374
43132
|
const now = deps.now ?? Date.now;
|
|
42375
43133
|
const start = now();
|
|
@@ -42400,6 +43158,56 @@ async function rerankHits(hits, queryVector, config2, request, deps) {
|
|
|
42400
43158
|
return rrfOrder;
|
|
42401
43159
|
}
|
|
42402
43160
|
}
|
|
43161
|
+
async function rerankWithCohere(rrfOrder, config2, request, deps, seam) {
|
|
43162
|
+
const baseOrder = [...rrfOrder];
|
|
43163
|
+
const now = deps.now ?? Date.now;
|
|
43164
|
+
const start = now();
|
|
43165
|
+
const window = Math.max(1, Math.trunc(config2.window));
|
|
43166
|
+
const head = baseOrder.slice(0, window);
|
|
43167
|
+
const tail = baseOrder.slice(window);
|
|
43168
|
+
const documents = head.map((h) => h.text);
|
|
43169
|
+
try {
|
|
43170
|
+
const timeoutMs = Math.max(1, Math.trunc(config2.providerTimeoutMs));
|
|
43171
|
+
const TIMED_OUT = /* @__PURE__ */ Symbol("rerank-timeout");
|
|
43172
|
+
let timer;
|
|
43173
|
+
const timeout = new Promise((resolve7) => {
|
|
43174
|
+
timer = setTimeout(() => resolve7(TIMED_OUT), timeoutMs);
|
|
43175
|
+
});
|
|
43176
|
+
let outcome;
|
|
43177
|
+
try {
|
|
43178
|
+
outcome = await Promise.race([seam.rerank(request.query, documents, head.length), timeout]);
|
|
43179
|
+
} finally {
|
|
43180
|
+
if (timer !== void 0)
|
|
43181
|
+
clearTimeout(timer);
|
|
43182
|
+
}
|
|
43183
|
+
if (outcome === TIMED_OUT || outcome.ok === false)
|
|
43184
|
+
return baseOrder;
|
|
43185
|
+
const scoreByIndex = /* @__PURE__ */ new Map();
|
|
43186
|
+
for (const r of outcome.results) {
|
|
43187
|
+
if (r.index >= 0 && r.index < head.length && !scoreByIndex.has(r.index)) {
|
|
43188
|
+
scoreByIndex.set(r.index, r.relevanceScore);
|
|
43189
|
+
}
|
|
43190
|
+
}
|
|
43191
|
+
const scoredSlots = [];
|
|
43192
|
+
for (let i = 0; i < head.length; i++) {
|
|
43193
|
+
if (scoreByIndex.has(i))
|
|
43194
|
+
scoredSlots.push(i);
|
|
43195
|
+
}
|
|
43196
|
+
const orderedByScore = scoredSlots.map((index) => ({ index, score: scoreByIndex.get(index) })).sort((a, b) => {
|
|
43197
|
+
if (b.score !== a.score)
|
|
43198
|
+
return b.score - a.score;
|
|
43199
|
+
return a.index - b.index;
|
|
43200
|
+
});
|
|
43201
|
+
const reorderedHead = head.slice();
|
|
43202
|
+
scoredSlots.forEach((slot, i) => {
|
|
43203
|
+
reorderedHead[slot] = head[orderedByScore[i].index];
|
|
43204
|
+
});
|
|
43205
|
+
void start;
|
|
43206
|
+
return [...reorderedHead, ...tail];
|
|
43207
|
+
} catch {
|
|
43208
|
+
return baseOrder;
|
|
43209
|
+
}
|
|
43210
|
+
}
|
|
42403
43211
|
function provenanceRank(source) {
|
|
42404
43212
|
if (source === "memories")
|
|
42405
43213
|
return 0;
|
|
@@ -42739,11 +43547,15 @@ async function recallMemories(request, deps) {
|
|
|
42739
43547
|
rowsToRankedArm(sessionsRows)
|
|
42740
43548
|
];
|
|
42741
43549
|
const { hits, sources } = fuseHits(arms, limit);
|
|
42742
|
-
const rerankerConfig = deps.reranker ?? {
|
|
42743
|
-
|
|
42744
|
-
|
|
42745
|
-
|
|
42746
|
-
|
|
43550
|
+
const rerankerConfig = deps.reranker ?? {
|
|
43551
|
+
strategy: DEFAULT_RERANKER,
|
|
43552
|
+
timeoutMs: DEFAULT_RERANKER_TIMEOUT_MS,
|
|
43553
|
+
providerTimeoutMs: DEFAULT_RERANKER_PROVIDER_TIMEOUT_MS,
|
|
43554
|
+
window: DEFAULT_RERANKER_WINDOW,
|
|
43555
|
+
cohereModel: DEFAULT_RERANKER_COHERE_MODEL
|
|
43556
|
+
};
|
|
43557
|
+
const skipRerank = rerankerConfig.strategy === "none" || rerankerConfig.strategy !== "cohere" && semanticRun === null;
|
|
43558
|
+
const ranked = skipRerank ? hits : await rerankHits(hits, semanticRun?.queryVector ?? null, rerankerConfig, request, deps);
|
|
42747
43559
|
const dedupConfig = deps.dedup ?? { enabled: DEFAULT_DEDUP_ENABLED, similarityThreshold: DEFAULT_DEDUP_SIMILARITY_THRESHOLD };
|
|
42748
43560
|
const deduped = await dedupHits(ranked, dedupConfig, request, deps);
|
|
42749
43561
|
const dedupedSources = deduped.length === ranked.length ? sources : [...new Set(deduped.map((h) => h.source))];
|
|
@@ -42772,470 +43584,6 @@ async function recallMemories(request, deps) {
|
|
|
42772
43584
|
}
|
|
42773
43585
|
}
|
|
42774
43586
|
|
|
42775
|
-
// dist/src/daemon/runtime/secrets/api.js
|
|
42776
|
-
function localDefaultScopeResolver(mode, defaultScope) {
|
|
42777
|
-
return {
|
|
42778
|
-
resolve(c) {
|
|
42779
|
-
const fromHeader = headerScopeResolver2.resolve(c);
|
|
42780
|
-
if (fromHeader !== null)
|
|
42781
|
-
return fromHeader;
|
|
42782
|
-
if (mode === "local" && defaultScope !== void 0) {
|
|
42783
|
-
return { org: defaultScope.org, workspace: defaultScope.workspace ?? "default" };
|
|
42784
|
-
}
|
|
42785
|
-
return null;
|
|
42786
|
-
}
|
|
42787
|
-
};
|
|
42788
|
-
}
|
|
42789
|
-
var headerScopeResolver2 = {
|
|
42790
|
-
resolve(c) {
|
|
42791
|
-
const org = c.req.header("x-honeycomb-org");
|
|
42792
|
-
if (org === void 0 || org.length === 0)
|
|
42793
|
-
return null;
|
|
42794
|
-
const workspace = c.req.header("x-honeycomb-workspace");
|
|
42795
|
-
const agentId = c.req.header("x-honeycomb-agent");
|
|
42796
|
-
const ws = workspace !== void 0 && workspace.length > 0 ? workspace : "default";
|
|
42797
|
-
return agentId !== void 0 && agentId.length > 0 ? { org, workspace: ws, agentId } : { org, workspace: ws };
|
|
42798
|
-
}
|
|
42799
|
-
};
|
|
42800
|
-
function mountSecretsApi(group, deps) {
|
|
42801
|
-
const scope = deps.scope ?? headerScopeResolver2;
|
|
42802
|
-
const store = deps.store;
|
|
42803
|
-
const runner = deps.execRunner;
|
|
42804
|
-
if (runner !== void 0) {
|
|
42805
|
-
group.post("/exec", async (c) => {
|
|
42806
|
-
const sc = scope.resolve(c);
|
|
42807
|
-
if (sc === null)
|
|
42808
|
-
return badTenancy(c);
|
|
42809
|
-
const request = await readExecRequest(c, sc);
|
|
42810
|
-
if (request === null) {
|
|
42811
|
-
return c.json({ error: "bad_request", reason: "exec body must carry a command" }, 400);
|
|
42812
|
-
}
|
|
42813
|
-
const res = runner.submit(request);
|
|
42814
|
-
if (!res.ok) {
|
|
42815
|
-
if (res.reason === "queue_full") {
|
|
42816
|
-
return c.json({ error: "queue_full", reason: "exec pool and queue are at capacity" }, 429);
|
|
42817
|
-
}
|
|
42818
|
-
return c.json({ error: "bad_request", reason: "invalid exec request" }, 400);
|
|
42819
|
-
}
|
|
42820
|
-
return c.json({ ok: true, jobId: res.jobId, status: "queued" }, 202);
|
|
42821
|
-
});
|
|
42822
|
-
group.get("/exec/:jobId", (c) => {
|
|
42823
|
-
const sc = scope.resolve(c);
|
|
42824
|
-
if (sc === null)
|
|
42825
|
-
return badTenancy(c);
|
|
42826
|
-
const jobId = c.req.param("jobId");
|
|
42827
|
-
const view = runner.getStatus(jobId, sc);
|
|
42828
|
-
if (view === null) {
|
|
42829
|
-
return c.json({ error: "not_found", reason: "no such exec job" }, 404);
|
|
42830
|
-
}
|
|
42831
|
-
return c.json(view);
|
|
42832
|
-
});
|
|
42833
|
-
group.all("/bitwarden/*", (c) => c.json({ error: "use_exec", reason: "reference a Bitwarden item via exec vaultRefs; values are never returned" }, 400));
|
|
42834
|
-
group.all("/1password/*", (c) => c.json({ error: "use_exec", reason: "reference a 1Password item via exec vaultRefs; values are never returned" }, 400));
|
|
42835
|
-
} else {
|
|
42836
|
-
group.post("/exec", (c) => notImplementedRoute(c, "POST /api/secrets/exec (secret_exec)"));
|
|
42837
|
-
group.get("/exec/:jobId", (c) => notImplementedRoute(c, "GET /api/secrets/exec/:jobId (exec status)"));
|
|
42838
|
-
group.all("/bitwarden/*", (c) => notImplementedRoute(c, "Bitwarden vault provider"));
|
|
42839
|
-
group.all("/1password/*", (c) => notImplementedRoute(c, "1Password vault provider"));
|
|
42840
|
-
}
|
|
42841
|
-
group.get("/", (c) => {
|
|
42842
|
-
const sc = scope.resolve(c);
|
|
42843
|
-
if (sc === null)
|
|
42844
|
-
return badTenancy(c);
|
|
42845
|
-
const names = store.listSecretNames(sc);
|
|
42846
|
-
return c.json({ names });
|
|
42847
|
-
});
|
|
42848
|
-
group.post("/:name", async (c) => {
|
|
42849
|
-
const sc = scope.resolve(c);
|
|
42850
|
-
if (sc === null)
|
|
42851
|
-
return badTenancy(c);
|
|
42852
|
-
const name = c.req.param("name");
|
|
42853
|
-
const value = await readValue(c);
|
|
42854
|
-
if (value === null) {
|
|
42855
|
-
return c.json({ error: "bad_request", reason: "request body must carry a string value" }, 400);
|
|
42856
|
-
}
|
|
42857
|
-
const res = await store.setSecret(name, value, sc);
|
|
42858
|
-
if (!res.ok) {
|
|
42859
|
-
if (res.reason === "invalid_name") {
|
|
42860
|
-
return c.json({ error: "bad_request", reason: "invalid secret name" }, 400);
|
|
42861
|
-
}
|
|
42862
|
-
return c.json({ error: "store_failed", reason: "could not store the secret" }, 502);
|
|
42863
|
-
}
|
|
42864
|
-
return c.json({ ok: true, name }, 201);
|
|
42865
|
-
});
|
|
42866
|
-
group.delete("/:name", (c) => {
|
|
42867
|
-
const sc = scope.resolve(c);
|
|
42868
|
-
if (sc === null)
|
|
42869
|
-
return badTenancy(c);
|
|
42870
|
-
const name = c.req.param("name");
|
|
42871
|
-
const res = store.deleteSecret(name, sc);
|
|
42872
|
-
if (!res.ok) {
|
|
42873
|
-
if (res.reason === "invalid_name") {
|
|
42874
|
-
return c.json({ error: "bad_request", reason: "invalid secret name" }, 400);
|
|
42875
|
-
}
|
|
42876
|
-
if (res.reason === "not_found") {
|
|
42877
|
-
return c.json({ error: "not_found", reason: "no such secret" }, 404);
|
|
42878
|
-
}
|
|
42879
|
-
return c.json({ error: "delete_failed", reason: "could not delete the secret" }, 502);
|
|
42880
|
-
}
|
|
42881
|
-
return c.json({ ok: true, name });
|
|
42882
|
-
});
|
|
42883
|
-
}
|
|
42884
|
-
function badTenancy(c) {
|
|
42885
|
-
return c.json({ error: "bad_request", reason: "x-honeycomb-org header is required" }, 400);
|
|
42886
|
-
}
|
|
42887
|
-
async function readValue(c) {
|
|
42888
|
-
const contentType = c.req.header("content-type") ?? "";
|
|
42889
|
-
if (contentType.includes("application/json")) {
|
|
42890
|
-
try {
|
|
42891
|
-
const body = await c.req.json();
|
|
42892
|
-
if (typeof body === "object" && body !== null) {
|
|
42893
|
-
const v = body.value;
|
|
42894
|
-
if (typeof v === "string" && v.length > 0)
|
|
42895
|
-
return v;
|
|
42896
|
-
}
|
|
42897
|
-
return null;
|
|
42898
|
-
} catch {
|
|
42899
|
-
return null;
|
|
42900
|
-
}
|
|
42901
|
-
}
|
|
42902
|
-
const text = await c.req.text();
|
|
42903
|
-
return text.length > 0 ? text : null;
|
|
42904
|
-
}
|
|
42905
|
-
function notImplementedRoute(c, what) {
|
|
42906
|
-
return c.json({ error: "not_implemented", reason: `${what} is implemented in PRD-012b` }, 501);
|
|
42907
|
-
}
|
|
42908
|
-
async function readExecRequest(c, scope) {
|
|
42909
|
-
let body;
|
|
42910
|
-
try {
|
|
42911
|
-
body = await c.req.json();
|
|
42912
|
-
} catch {
|
|
42913
|
-
return null;
|
|
42914
|
-
}
|
|
42915
|
-
if (typeof body !== "object" || body === null)
|
|
42916
|
-
return null;
|
|
42917
|
-
const b = body;
|
|
42918
|
-
const command = b.command;
|
|
42919
|
-
if (typeof command !== "string" || command.length === 0)
|
|
42920
|
-
return null;
|
|
42921
|
-
const args = Array.isArray(b.args) ? b.args.filter((a) => typeof a === "string") : [];
|
|
42922
|
-
const secretNames = Array.isArray(b.secretNames) ? b.secretNames.filter((n) => typeof n === "string") : [];
|
|
42923
|
-
const vaultRefs = {};
|
|
42924
|
-
if (typeof b.vaultRefs === "object" && b.vaultRefs !== null) {
|
|
42925
|
-
for (const [k, v] of Object.entries(b.vaultRefs)) {
|
|
42926
|
-
if (typeof v === "string")
|
|
42927
|
-
vaultRefs[k] = v;
|
|
42928
|
-
}
|
|
42929
|
-
}
|
|
42930
|
-
const timeoutMs = typeof b.timeoutMs === "number" ? b.timeoutMs : void 0;
|
|
42931
|
-
return { command, args, secretNames, vaultRefs, scope, timeoutMs };
|
|
42932
|
-
}
|
|
42933
|
-
|
|
42934
|
-
// dist/src/daemon/runtime/vault/catalog.js
|
|
42935
|
-
var PROVIDER_CATALOG = Object.freeze([
|
|
42936
|
-
Object.freeze({
|
|
42937
|
-
id: "anthropic",
|
|
42938
|
-
label: "Anthropic",
|
|
42939
|
-
models: Object.freeze(["claude-sonnet-4-6", "claude-opus-4-8"]),
|
|
42940
|
-
openEnded: false
|
|
42941
|
-
}),
|
|
42942
|
-
Object.freeze({
|
|
42943
|
-
id: "openai",
|
|
42944
|
-
label: "OpenAI",
|
|
42945
|
-
models: Object.freeze(["gpt-4o", "gpt-4o-mini", "gpt-4.1"]),
|
|
42946
|
-
openEnded: false
|
|
42947
|
-
}),
|
|
42948
|
-
Object.freeze({
|
|
42949
|
-
id: "openrouter",
|
|
42950
|
-
label: "OpenRouter",
|
|
42951
|
-
// Suggestions only — OpenRouter accepts a free-form `vendor/model` id (passthrough).
|
|
42952
|
-
models: Object.freeze(["anthropic/claude-sonnet-4.6", "openai/gpt-4o"]),
|
|
42953
|
-
openEnded: true
|
|
42954
|
-
})
|
|
42955
|
-
]);
|
|
42956
|
-
function providerEntry(provider) {
|
|
42957
|
-
return PROVIDER_CATALOG.find((p) => p.id === provider);
|
|
42958
|
-
}
|
|
42959
|
-
function isValidProviderModel(provider, model) {
|
|
42960
|
-
const entry = providerEntry(provider);
|
|
42961
|
-
if (entry === void 0)
|
|
42962
|
-
return false;
|
|
42963
|
-
if (typeof model !== "string" || model.length === 0)
|
|
42964
|
-
return false;
|
|
42965
|
-
if (entry.openEnded)
|
|
42966
|
-
return true;
|
|
42967
|
-
return entry.models.includes(model);
|
|
42968
|
-
}
|
|
42969
|
-
function catalogView() {
|
|
42970
|
-
return PROVIDER_CATALOG;
|
|
42971
|
-
}
|
|
42972
|
-
|
|
42973
|
-
// dist/src/daemon/runtime/secrets/contracts.js
|
|
42974
|
-
import { homedir as homedir20, hostname as hostname4, userInfo } from "node:os";
|
|
42975
|
-
var SECRET_NAME_PATTERN = /^[A-Za-z0-9_.-]+$/;
|
|
42976
|
-
var MAX_SECRET_NAME_LENGTH = 128;
|
|
42977
|
-
function isValidSecretName(value) {
|
|
42978
|
-
if (typeof value !== "string")
|
|
42979
|
-
return false;
|
|
42980
|
-
if (value.length === 0 || value.length > MAX_SECRET_NAME_LENGTH)
|
|
42981
|
-
return false;
|
|
42982
|
-
if (value === "." || value === "..")
|
|
42983
|
-
return false;
|
|
42984
|
-
if (value.includes("/") || value.includes("\\") || value.includes("\0"))
|
|
42985
|
-
return false;
|
|
42986
|
-
return SECRET_NAME_PATTERN.test(value);
|
|
42987
|
-
}
|
|
42988
|
-
function asSecretName(value) {
|
|
42989
|
-
return isValidSecretName(value) ? value : null;
|
|
42990
|
-
}
|
|
42991
|
-
function isSecretRecord(value) {
|
|
42992
|
-
if (typeof value !== "object" || value === null)
|
|
42993
|
-
return false;
|
|
42994
|
-
const r = value;
|
|
42995
|
-
if (typeof r.nonce !== "string" || typeof r.ciphertext !== "string" || typeof r.createdAt !== "string") {
|
|
42996
|
-
return false;
|
|
42997
|
-
}
|
|
42998
|
-
const scope = r.scope;
|
|
42999
|
-
if (typeof scope !== "object" || scope === null)
|
|
43000
|
-
return false;
|
|
43001
|
-
const s = scope;
|
|
43002
|
-
if (typeof s.org !== "string" || typeof s.workspace !== "string")
|
|
43003
|
-
return false;
|
|
43004
|
-
if (s.agentId !== void 0 && typeof s.agentId !== "string")
|
|
43005
|
-
return false;
|
|
43006
|
-
return true;
|
|
43007
|
-
}
|
|
43008
|
-
var MACHINE_KEY_DIR_NAME = ".honeycomb";
|
|
43009
|
-
var MACHINE_KEY_FILE_NAME = ".machine-key";
|
|
43010
|
-
function hostnameUserFallbackId() {
|
|
43011
|
-
let user = "";
|
|
43012
|
-
try {
|
|
43013
|
-
user = userInfo().username;
|
|
43014
|
-
} catch {
|
|
43015
|
-
user = "";
|
|
43016
|
-
}
|
|
43017
|
-
return `host:${hostname4()}|user:${user}|home:${homedir20()}`;
|
|
43018
|
-
}
|
|
43019
|
-
|
|
43020
|
-
// dist/src/daemon/runtime/vault/contracts.js
|
|
43021
|
-
function asRecordClass(value) {
|
|
43022
|
-
return isValidSecretName(value) ? value : null;
|
|
43023
|
-
}
|
|
43024
|
-
|
|
43025
|
-
// dist/src/daemon/runtime/vault/registry.js
|
|
43026
|
-
var SECRET_CLASS = "secret";
|
|
43027
|
-
var SETTING_CLASS = "setting";
|
|
43028
|
-
var SecretValueSchema = external_exports.string().min(1);
|
|
43029
|
-
var SettingValueSchema = external_exports.union([external_exports.string(), external_exports.number().finite(), external_exports.boolean()]);
|
|
43030
|
-
var SECRET_DESCRIPTOR = Object.freeze({
|
|
43031
|
-
id: SECRET_CLASS,
|
|
43032
|
-
posture: "internal-only",
|
|
43033
|
-
schema: SecretValueSchema
|
|
43034
|
-
});
|
|
43035
|
-
var SETTING_DESCRIPTOR = Object.freeze({
|
|
43036
|
-
id: SETTING_CLASS,
|
|
43037
|
-
posture: "daemon-readable",
|
|
43038
|
-
schema: SettingValueSchema
|
|
43039
|
-
});
|
|
43040
|
-
var VaultRegistry = class {
|
|
43041
|
-
table;
|
|
43042
|
-
constructor(descriptors) {
|
|
43043
|
-
this.table = /* @__PURE__ */ new Map();
|
|
43044
|
-
for (const d of descriptors)
|
|
43045
|
-
this.table.set(d.id, d);
|
|
43046
|
-
}
|
|
43047
|
-
/**
|
|
43048
|
-
* Register a new record class (D-7). Validates the id is traversal-proof (a class is an
|
|
43049
|
-
* on-disk segment) and that the posture is one the store understands, then adds the
|
|
43050
|
-
* descriptor. Re-registering an existing id REPLACES it (so a test can swap a throwaway
|
|
43051
|
-
* class); registering the built-in `secret`/`setting` ids is allowed but discouraged —
|
|
43052
|
-
* their posture must not be loosened. Returns the registry for chaining.
|
|
43053
|
-
*
|
|
43054
|
-
* Throws on an invalid (traversal-unsafe) class id — that is a programming error, not a
|
|
43055
|
-
* runtime input, so it fails loud rather than silently dropping the class.
|
|
43056
|
-
*/
|
|
43057
|
-
registerClass(descriptor) {
|
|
43058
|
-
const safe = asRecordClass(descriptor.id);
|
|
43059
|
-
if (safe === null) {
|
|
43060
|
-
throw new Error(`vault.registerClass: invalid (traversal-unsafe) class id`);
|
|
43061
|
-
}
|
|
43062
|
-
this.table.set(descriptor.id, descriptor);
|
|
43063
|
-
return this;
|
|
43064
|
-
}
|
|
43065
|
-
/** Whether a class id is registered. */
|
|
43066
|
-
has(klass) {
|
|
43067
|
-
return this.table.has(klass);
|
|
43068
|
-
}
|
|
43069
|
-
/** The registered class ids (sorted), for diagnostics — never values. */
|
|
43070
|
-
classIds() {
|
|
43071
|
-
return [...this.table.keys()].sort();
|
|
43072
|
-
}
|
|
43073
|
-
/**
|
|
43074
|
-
* Resolve a class's descriptor for a WRITE, validating the value against the class
|
|
43075
|
-
* schema (zod-at-boundary). Returns `unknown_class` for an unregistered class or
|
|
43076
|
-
* `invalid_value` when the value fails the schema — both fail-closed (nothing is
|
|
43077
|
-
* written). On success the descriptor (with the validated value available via the
|
|
43078
|
-
* caller's re-parse) is returned.
|
|
43079
|
-
*/
|
|
43080
|
-
resolveForWrite(klass, value) {
|
|
43081
|
-
const descriptor = this.table.get(klass);
|
|
43082
|
-
if (descriptor === void 0)
|
|
43083
|
-
return { ok: false, reason: "unknown_class" };
|
|
43084
|
-
const parsed = descriptor.schema.safeParse(value);
|
|
43085
|
-
if (!parsed.success)
|
|
43086
|
-
return { ok: false, reason: "invalid_value" };
|
|
43087
|
-
return { ok: true, descriptor };
|
|
43088
|
-
}
|
|
43089
|
-
/**
|
|
43090
|
-
* The POSTURE GATE (a-AC-2). Resolve a class's descriptor for a READ that intends to
|
|
43091
|
-
* RETURN the value to a surface (the `getSetting` path). REJECTS a class whose posture
|
|
43092
|
-
* is `internal-only` with `not_readable` — so a `secret` can NEVER be read back through
|
|
43093
|
-
* the daemon-readable accessor. An unknown class is `unknown_class`. This is the single
|
|
43094
|
-
* point where the secret-vs-setting security boundary is enforced, as data.
|
|
43095
|
-
*/
|
|
43096
|
-
assertReadable(klass) {
|
|
43097
|
-
const descriptor = this.table.get(klass);
|
|
43098
|
-
if (descriptor === void 0)
|
|
43099
|
-
return { ok: false, reason: "unknown_class" };
|
|
43100
|
-
if (descriptor.posture !== "daemon-readable")
|
|
43101
|
-
return { ok: false, reason: "not_readable" };
|
|
43102
|
-
return { ok: true, descriptor };
|
|
43103
|
-
}
|
|
43104
|
-
/** Resolve a descriptor with no value/posture check (internal callers that already gate). */
|
|
43105
|
-
descriptorOf(klass) {
|
|
43106
|
-
return this.table.get(klass);
|
|
43107
|
-
}
|
|
43108
|
-
};
|
|
43109
|
-
function createVaultRegistry(extra = []) {
|
|
43110
|
-
return new VaultRegistry([SECRET_DESCRIPTOR, SETTING_DESCRIPTOR, ...extra]);
|
|
43111
|
-
}
|
|
43112
|
-
|
|
43113
|
-
// dist/src/daemon/runtime/vault/api.js
|
|
43114
|
-
var SETTINGS_GROUP = "/api/settings";
|
|
43115
|
-
var KNOWN_SETTING_KEYS = ["activeProvider", "activeModel", "pollinating.enabled", "recallMode"];
|
|
43116
|
-
var RECALL_MODES = ["keyword", "semantic", "hybrid"];
|
|
43117
|
-
function isValidRecallMode(value) {
|
|
43118
|
-
return RECALL_MODES.includes(value);
|
|
43119
|
-
}
|
|
43120
|
-
var DASHBOARD_PREF_PREFIX = "dashboard.";
|
|
43121
|
-
function isKnownSettingKey(key) {
|
|
43122
|
-
if (KNOWN_SETTING_KEYS.includes(key))
|
|
43123
|
-
return true;
|
|
43124
|
-
return key.startsWith(DASHBOARD_PREF_PREFIX) && key.length > DASHBOARD_PREF_PREFIX.length;
|
|
43125
|
-
}
|
|
43126
|
-
function mountSettingsGroup(group, deps) {
|
|
43127
|
-
const scope = deps.scope ?? headerScopeResolver2;
|
|
43128
|
-
const store = deps.store;
|
|
43129
|
-
group.get("/", async (c) => {
|
|
43130
|
-
const sc = scope.resolve(c);
|
|
43131
|
-
if (sc === null)
|
|
43132
|
-
return badTenancy2(c);
|
|
43133
|
-
const keys = store.listSettingKeys(sc);
|
|
43134
|
-
const settings = {};
|
|
43135
|
-
for (const key of keys) {
|
|
43136
|
-
const res = await store.getSetting(key, sc);
|
|
43137
|
-
if (res.ok)
|
|
43138
|
-
settings[key] = res.value;
|
|
43139
|
-
}
|
|
43140
|
-
return c.json({ settings, catalog: catalogView() });
|
|
43141
|
-
});
|
|
43142
|
-
group.get("/:key", async (c) => {
|
|
43143
|
-
const sc = scope.resolve(c);
|
|
43144
|
-
if (sc === null)
|
|
43145
|
-
return badTenancy2(c);
|
|
43146
|
-
const key = c.req.param("key");
|
|
43147
|
-
if (!isKnownSettingKey(key)) {
|
|
43148
|
-
return c.json({ error: "not_found", reason: "no such setting" }, 404);
|
|
43149
|
-
}
|
|
43150
|
-
const res = await store.getSetting(key, sc);
|
|
43151
|
-
if (!res.ok) {
|
|
43152
|
-
if (res.reason === "not_found")
|
|
43153
|
-
return c.json({ error: "not_found", reason: "no such setting" }, 404);
|
|
43154
|
-
if (res.reason === "not_readable")
|
|
43155
|
-
return c.json({ error: "not_found", reason: "no such setting" }, 404);
|
|
43156
|
-
return c.json({ error: "read_failed", reason: "could not read the setting" }, 502);
|
|
43157
|
-
}
|
|
43158
|
-
return c.json({ key, value: res.value });
|
|
43159
|
-
});
|
|
43160
|
-
group.post("/:key", async (c) => {
|
|
43161
|
-
const sc = scope.resolve(c);
|
|
43162
|
-
if (sc === null)
|
|
43163
|
-
return badTenancy2(c);
|
|
43164
|
-
const key = c.req.param("key");
|
|
43165
|
-
if (!isKnownSettingKey(key)) {
|
|
43166
|
-
return c.json({ error: "bad_request", reason: "unknown setting key" }, 400);
|
|
43167
|
-
}
|
|
43168
|
-
const value = await readSettingValue(c);
|
|
43169
|
-
if (value === null) {
|
|
43170
|
-
return c.json({ error: "bad_request", reason: "request body must carry a scalar value" }, 400);
|
|
43171
|
-
}
|
|
43172
|
-
const semanticError = await validateSettingSemantics(store, sc, key, value);
|
|
43173
|
-
if (semanticError !== null) {
|
|
43174
|
-
return c.json({ error: "bad_request", reason: semanticError }, 400);
|
|
43175
|
-
}
|
|
43176
|
-
const res = await store.setSetting(key, value, sc);
|
|
43177
|
-
if (!res.ok) {
|
|
43178
|
-
if (res.reason === "invalid_value") {
|
|
43179
|
-
return c.json({ error: "bad_request", reason: "invalid setting value" }, 400);
|
|
43180
|
-
}
|
|
43181
|
-
if (res.reason === "not_readable" || res.reason === "unknown_class") {
|
|
43182
|
-
return c.json({ error: "bad_request", reason: "setting class is not writable" }, 400);
|
|
43183
|
-
}
|
|
43184
|
-
return c.json({ error: "store_failed", reason: "could not store the setting" }, 502);
|
|
43185
|
-
}
|
|
43186
|
-
return c.json({ ok: true, key, value }, 201);
|
|
43187
|
-
});
|
|
43188
|
-
}
|
|
43189
|
-
function mountSettingsApi(daemon, deps) {
|
|
43190
|
-
const group = daemon.group(SETTINGS_GROUP);
|
|
43191
|
-
if (group === void 0)
|
|
43192
|
-
return;
|
|
43193
|
-
mountSettingsGroup(group, deps);
|
|
43194
|
-
}
|
|
43195
|
-
function badTenancy2(c) {
|
|
43196
|
-
return c.json({ error: "bad_request", reason: "x-honeycomb-org header is required" }, 400);
|
|
43197
|
-
}
|
|
43198
|
-
async function readSettingValue(c) {
|
|
43199
|
-
const contentType = c.req.header("content-type") ?? "";
|
|
43200
|
-
if (contentType.includes("application/json")) {
|
|
43201
|
-
try {
|
|
43202
|
-
const body = await c.req.json();
|
|
43203
|
-
if (typeof body === "object" && body !== null) {
|
|
43204
|
-
const v = body.value;
|
|
43205
|
-
const parsed = SettingValueSchema.safeParse(v);
|
|
43206
|
-
return parsed.success ? parsed.data : null;
|
|
43207
|
-
}
|
|
43208
|
-
return null;
|
|
43209
|
-
} catch {
|
|
43210
|
-
return null;
|
|
43211
|
-
}
|
|
43212
|
-
}
|
|
43213
|
-
const text = await c.req.text();
|
|
43214
|
-
return text.length > 0 ? text : null;
|
|
43215
|
-
}
|
|
43216
|
-
async function validateSettingSemantics(store, scope, key, value) {
|
|
43217
|
-
if (key === "activeProvider") {
|
|
43218
|
-
if (providerEntry(String(value)) === void 0)
|
|
43219
|
-
return "unknown provider";
|
|
43220
|
-
return null;
|
|
43221
|
-
}
|
|
43222
|
-
if (key === "activeModel") {
|
|
43223
|
-
const provRes = await store.getSetting("activeProvider", scope);
|
|
43224
|
-
const provider = provRes.ok ? String(provRes.value) : "";
|
|
43225
|
-
if (provider.length === 0)
|
|
43226
|
-
return "set activeProvider before activeModel";
|
|
43227
|
-
if (!isValidProviderModel(provider, String(value)))
|
|
43228
|
-
return "model not in provider catalog";
|
|
43229
|
-
return null;
|
|
43230
|
-
}
|
|
43231
|
-
if (key === "recallMode") {
|
|
43232
|
-
if (!isValidRecallMode(String(value)))
|
|
43233
|
-
return "recallMode must be keyword, semantic, or hybrid";
|
|
43234
|
-
return null;
|
|
43235
|
-
}
|
|
43236
|
-
return null;
|
|
43237
|
-
}
|
|
43238
|
-
|
|
43239
43587
|
// dist/src/daemon/runtime/memories/calibration-store.js
|
|
43240
43588
|
function coldStart(bins) {
|
|
43241
43589
|
return {
|
|
@@ -44273,7 +44621,13 @@ function mountMemoriesApi(daemon, options) {
|
|
|
44273
44621
|
// PRD-058a: the per-request recency override (per-class half-lives + activation exponent).
|
|
44274
44622
|
...recency !== void 0 ? { recency } : {},
|
|
44275
44623
|
// PRD-058b: the κ gate's conflict-suppression seam (drops the κ = ρ open-conflict loser).
|
|
44276
|
-
...options.conflictSuppression !== void 0 ? { conflictSuppression: options.conflictSuppression } : {}
|
|
44624
|
+
...options.conflictSuppression !== void 0 ? { conflictSuppression: options.conflictSuppression } : {},
|
|
44625
|
+
// PRD-063c: the operator-selected reranker config + the Cohere-via-Portkey seam. The
|
|
44626
|
+
// `cohere` strategy activates ONLY when BOTH are present (the strategy is `cohere` AND the
|
|
44627
|
+
// gateway-on seam is wired); otherwise the engine keeps the RRF order / runs the local
|
|
44628
|
+
// cosine path — byte-identical to today (c-AC-4).
|
|
44629
|
+
...options.reranker !== void 0 ? { reranker: options.reranker } : {},
|
|
44630
|
+
...options.cohereRerank !== void 0 ? { cohereRerank: options.cohereRerank } : {}
|
|
44277
44631
|
});
|
|
44278
44632
|
logDegradedRecall(options.logger, result);
|
|
44279
44633
|
logProjectScopeDegraded(options.logger, project);
|
|
@@ -45741,7 +46095,7 @@ var DISCOVERY_POLLS = 20;
|
|
|
45741
46095
|
var DISCOVERY_POLL_DELAY_MS = 400;
|
|
45742
46096
|
var DISCOVERY_STABLE_BREAK = 4;
|
|
45743
46097
|
function sleep(ms) {
|
|
45744
|
-
return new Promise((
|
|
46098
|
+
return new Promise((resolve7) => setTimeout(resolve7, ms));
|
|
45745
46099
|
}
|
|
45746
46100
|
function nowIso7() {
|
|
45747
46101
|
return (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -46979,7 +47333,7 @@ function guardedLookup(allowLoopback) {
|
|
|
46979
47333
|
}
|
|
46980
47334
|
function requestOnce(url2, timeoutMs, maxBytes, allowLoopback) {
|
|
46981
47335
|
const requestFn = url2.protocol === "https:" ? httpsRequest : httpRequest;
|
|
46982
|
-
return new Promise((
|
|
47336
|
+
return new Promise((resolve7, reject) => {
|
|
46983
47337
|
const req = requestFn(url2, {
|
|
46984
47338
|
method: "GET",
|
|
46985
47339
|
headers: { "user-agent": USER_AGENT, accept: "*/*" },
|
|
@@ -47006,7 +47360,7 @@ function requestOnce(url2, timeoutMs, maxBytes, allowLoopback) {
|
|
|
47006
47360
|
if (aborted2)
|
|
47007
47361
|
return;
|
|
47008
47362
|
const location = res.headers.location;
|
|
47009
|
-
|
|
47363
|
+
resolve7({
|
|
47010
47364
|
status: res.statusCode ?? 0,
|
|
47011
47365
|
location: typeof location === "string" ? location : void 0,
|
|
47012
47366
|
contentType: typeof res.headers["content-type"] === "string" ? res.headers["content-type"] : "",
|
|
@@ -48180,7 +48534,7 @@ function buildSourcesApiDeps(options) {
|
|
|
48180
48534
|
// dist/src/daemon/runtime/secrets/store.js
|
|
48181
48535
|
import { execFileSync as execFileSync6 } from "node:child_process";
|
|
48182
48536
|
import { randomBytes as randomBytes5 } from "node:crypto";
|
|
48183
|
-
import { appendFileSync, existsSync as existsSync18, mkdirSync as mkdirSync16, readdirSync as readdirSync4, readFileSync as readFileSync18, rmSync as
|
|
48537
|
+
import { appendFileSync, existsSync as existsSync18, mkdirSync as mkdirSync16, readdirSync as readdirSync4, readFileSync as readFileSync18, rmSync as rmSync8, statSync as statSync3, writeFileSync as writeFileSync13 } from "node:fs";
|
|
48184
48538
|
import { homedir as homedir21 } from "node:os";
|
|
48185
48539
|
import { join as join27 } from "node:path";
|
|
48186
48540
|
|
|
@@ -49052,7 +49406,7 @@ var SecretsStore = class {
|
|
|
49052
49406
|
return { ok: false, reason: "not_found" };
|
|
49053
49407
|
}
|
|
49054
49408
|
try {
|
|
49055
|
-
|
|
49409
|
+
rmSync8(file2);
|
|
49056
49410
|
this.audit("deleted", scope, "ok", safe);
|
|
49057
49411
|
return { ok: true };
|
|
49058
49412
|
} catch {
|
|
@@ -49173,7 +49527,7 @@ function stripRefWrapper(ref) {
|
|
|
49173
49527
|
}
|
|
49174
49528
|
|
|
49175
49529
|
// dist/src/daemon/runtime/vault/store.js
|
|
49176
|
-
import { appendFileSync as appendFileSync2, existsSync as existsSync19, mkdirSync as mkdirSync17, readdirSync as readdirSync5, readFileSync as readFileSync19, rmSync as
|
|
49530
|
+
import { appendFileSync as appendFileSync2, existsSync as existsSync19, mkdirSync as mkdirSync17, readdirSync as readdirSync5, readFileSync as readFileSync19, rmSync as rmSync9, writeFileSync as writeFileSync14 } from "node:fs";
|
|
49177
49531
|
import { join as join28 } from "node:path";
|
|
49178
49532
|
var VAULT_DIR_NAME = ".vault";
|
|
49179
49533
|
var VAULT_AUDIT_FILE_NAME = "vault-audit.ndjson";
|
|
@@ -49347,7 +49701,7 @@ var VaultStore = class {
|
|
|
49347
49701
|
return { ok: false, reason: "not_found" };
|
|
49348
49702
|
}
|
|
49349
49703
|
try {
|
|
49350
|
-
|
|
49704
|
+
rmSync9(file2);
|
|
49351
49705
|
this.audit(safeClass, "deleted", scope, "ok", safe);
|
|
49352
49706
|
return { ok: true };
|
|
49353
49707
|
} catch {
|
|
@@ -50286,94 +50640,7 @@ var noopUsageSink = {
|
|
|
50286
50640
|
record() {
|
|
50287
50641
|
}
|
|
50288
50642
|
};
|
|
50289
|
-
|
|
50290
|
-
type: external_exports.string(),
|
|
50291
|
-
text: external_exports.string().optional()
|
|
50292
|
-
});
|
|
50293
|
-
var AnthropicUsageSchema = external_exports.object({
|
|
50294
|
-
input_tokens: external_exports.number().int().nonnegative().catch(0).default(0),
|
|
50295
|
-
output_tokens: external_exports.number().int().nonnegative().catch(0).default(0),
|
|
50296
|
-
cache_read_input_tokens: external_exports.number().int().nonnegative().catch(0).default(0),
|
|
50297
|
-
cache_creation_input_tokens: external_exports.number().int().nonnegative().catch(0).default(0)
|
|
50298
|
-
});
|
|
50299
|
-
var ZERO_USAGE = {
|
|
50300
|
-
input_tokens: 0,
|
|
50301
|
-
output_tokens: 0,
|
|
50302
|
-
cache_read_input_tokens: 0,
|
|
50303
|
-
cache_creation_input_tokens: 0
|
|
50304
|
-
};
|
|
50305
|
-
var AnthropicMessagesResponseSchema = external_exports.object({
|
|
50306
|
-
content: external_exports.array(AnthropicContentBlockSchema).default([]),
|
|
50307
|
-
// Finding (usage-failsoft): `.default(ZERO_USAGE)` only covers `usage === undefined`. A response with
|
|
50308
|
-
// `usage: null` or a malformed `usage` object would FAIL the object parse and -- because this field is
|
|
50309
|
-
// part of the whole-response schema -- bubble up to a 502 that DROPS an otherwise-valid completion.
|
|
50310
|
-
// `.catch(ZERO_USAGE)` makes ANY invalid value (null, a string, a malformed object) fall back to
|
|
50311
|
-
// zero-usage so a valid completion is NEVER dropped over its (side-channel) usage block.
|
|
50312
|
-
usage: AnthropicUsageSchema.default(ZERO_USAGE).catch(ZERO_USAGE)
|
|
50313
|
-
});
|
|
50314
|
-
function toAnthropicBody(call, defaultMaxTokens) {
|
|
50315
|
-
const systemParts = [];
|
|
50316
|
-
const messages = [];
|
|
50317
|
-
for (const m of call.request.messages) {
|
|
50318
|
-
if (m.role === "system") {
|
|
50319
|
-
systemParts.push(m.content);
|
|
50320
|
-
continue;
|
|
50321
|
-
}
|
|
50322
|
-
const role = m.role === "assistant" ? "assistant" : "user";
|
|
50323
|
-
messages.push({ role, content: m.content });
|
|
50324
|
-
}
|
|
50325
|
-
const maxTokens = call.request.maxTokens ?? defaultMaxTokens;
|
|
50326
|
-
return {
|
|
50327
|
-
model: call.target.model,
|
|
50328
|
-
max_tokens: maxTokens,
|
|
50329
|
-
...systemParts.length > 0 ? { system: systemParts.join("\n\n") } : {},
|
|
50330
|
-
messages
|
|
50331
|
-
};
|
|
50332
|
-
}
|
|
50333
|
-
function joinContentText(content) {
|
|
50334
|
-
return content.filter((b) => b.type === "text" && typeof b.text === "string").map((b) => b.text).join("");
|
|
50335
|
-
}
|
|
50336
|
-
function createAnthropicTransport(deps = {}) {
|
|
50337
|
-
const doFetch = deps.fetch ?? globalThis.fetch;
|
|
50338
|
-
const url2 = deps.baseUrl ?? ANTHROPIC_MESSAGES_URL;
|
|
50339
|
-
const defaultMaxTokens = deps.defaultMaxTokens ?? DEFAULT_MAX_TOKENS;
|
|
50340
|
-
const usageSink = deps.usageSink ?? noopUsageSink;
|
|
50341
|
-
async function post(call) {
|
|
50342
|
-
const body = toAnthropicBody(call, defaultMaxTokens);
|
|
50343
|
-
let res;
|
|
50344
|
-
try {
|
|
50345
|
-
res = await doFetch(url2, {
|
|
50346
|
-
method: "POST",
|
|
50347
|
-
headers: {
|
|
50348
|
-
"x-api-key": call.apiKey,
|
|
50349
|
-
"anthropic-version": ANTHROPIC_VERSION,
|
|
50350
|
-
"content-type": "application/json"
|
|
50351
|
-
},
|
|
50352
|
-
body: JSON.stringify(body)
|
|
50353
|
-
});
|
|
50354
|
-
} catch (err) {
|
|
50355
|
-
const detail = err instanceof Error ? err.name : "network error";
|
|
50356
|
-
throw new ProviderError(503, `anthropic transport: request failed (${detail})`);
|
|
50357
|
-
}
|
|
50358
|
-
if (!res.ok) {
|
|
50359
|
-
throw new ProviderError(res.status, `anthropic transport: provider returned status ${res.status}`);
|
|
50360
|
-
}
|
|
50361
|
-
const raw2 = await res.text().then((t) => safeJson2(t));
|
|
50362
|
-
const parsed = AnthropicMessagesResponseSchema.safeParse(raw2);
|
|
50363
|
-
if (!parsed.success) {
|
|
50364
|
-
throw new ProviderError(502, "anthropic transport: malformed provider response");
|
|
50365
|
-
}
|
|
50366
|
-
const u = parsed.data.usage;
|
|
50367
|
-
const usage = {
|
|
50368
|
-
model: call.target.model,
|
|
50369
|
-
workload: call.request.workload,
|
|
50370
|
-
inputTokens: u.input_tokens,
|
|
50371
|
-
outputTokens: u.output_tokens,
|
|
50372
|
-
cacheReadInputTokens: u.cache_read_input_tokens,
|
|
50373
|
-
cacheCreationInputTokens: u.cache_creation_input_tokens
|
|
50374
|
-
};
|
|
50375
|
-
return { output: joinContentText(parsed.data.content), usage };
|
|
50376
|
-
}
|
|
50643
|
+
function usageReportingTransport(post, usageSink) {
|
|
50377
50644
|
function reportUsage(usage) {
|
|
50378
50645
|
try {
|
|
50379
50646
|
usageSink.record(usage);
|
|
@@ -50396,15 +50663,209 @@ function createAnthropicTransport(deps = {}) {
|
|
|
50396
50663
|
}
|
|
50397
50664
|
};
|
|
50398
50665
|
}
|
|
50399
|
-
function
|
|
50666
|
+
function safeJsonParse(text) {
|
|
50400
50667
|
try {
|
|
50401
50668
|
return JSON.parse(text);
|
|
50402
50669
|
} catch {
|
|
50403
50670
|
return void 0;
|
|
50404
50671
|
}
|
|
50405
50672
|
}
|
|
50673
|
+
var AnthropicContentBlockSchema = external_exports.object({
|
|
50674
|
+
type: external_exports.string(),
|
|
50675
|
+
text: external_exports.string().optional()
|
|
50676
|
+
});
|
|
50677
|
+
var AnthropicUsageSchema = external_exports.object({
|
|
50678
|
+
input_tokens: external_exports.number().int().nonnegative().catch(0).default(0),
|
|
50679
|
+
output_tokens: external_exports.number().int().nonnegative().catch(0).default(0),
|
|
50680
|
+
cache_read_input_tokens: external_exports.number().int().nonnegative().catch(0).default(0),
|
|
50681
|
+
cache_creation_input_tokens: external_exports.number().int().nonnegative().catch(0).default(0)
|
|
50682
|
+
});
|
|
50683
|
+
var ZERO_USAGE = {
|
|
50684
|
+
input_tokens: 0,
|
|
50685
|
+
output_tokens: 0,
|
|
50686
|
+
cache_read_input_tokens: 0,
|
|
50687
|
+
cache_creation_input_tokens: 0
|
|
50688
|
+
};
|
|
50689
|
+
var AnthropicMessagesResponseSchema = external_exports.object({
|
|
50690
|
+
content: external_exports.array(AnthropicContentBlockSchema).default([]),
|
|
50691
|
+
// Finding (usage-failsoft): `.default(ZERO_USAGE)` only covers `usage === undefined`. A response with
|
|
50692
|
+
// `usage: null` or a malformed `usage` object would FAIL the object parse and -- because this field is
|
|
50693
|
+
// part of the whole-response schema -- bubble up to a 502 that DROPS an otherwise-valid completion.
|
|
50694
|
+
// `.catch(ZERO_USAGE)` makes ANY invalid value (null, a string, a malformed object) fall back to
|
|
50695
|
+
// zero-usage so a valid completion is NEVER dropped over its (side-channel) usage block.
|
|
50696
|
+
usage: AnthropicUsageSchema.default(ZERO_USAGE).catch(ZERO_USAGE)
|
|
50697
|
+
});
|
|
50698
|
+
function toAnthropicBody(call, defaultMaxTokens) {
|
|
50699
|
+
const systemParts = [];
|
|
50700
|
+
const messages = [];
|
|
50701
|
+
for (const m of call.request.messages) {
|
|
50702
|
+
if (m.role === "system") {
|
|
50703
|
+
systemParts.push(m.content);
|
|
50704
|
+
continue;
|
|
50705
|
+
}
|
|
50706
|
+
const role = m.role === "assistant" ? "assistant" : "user";
|
|
50707
|
+
messages.push({ role, content: m.content });
|
|
50708
|
+
}
|
|
50709
|
+
const maxTokens = call.request.maxTokens ?? defaultMaxTokens;
|
|
50710
|
+
return {
|
|
50711
|
+
model: call.target.model,
|
|
50712
|
+
max_tokens: maxTokens,
|
|
50713
|
+
...systemParts.length > 0 ? { system: systemParts.join("\n\n") } : {},
|
|
50714
|
+
messages
|
|
50715
|
+
};
|
|
50716
|
+
}
|
|
50717
|
+
function joinContentText(content) {
|
|
50718
|
+
return content.filter((b) => b.type === "text" && typeof b.text === "string").map((b) => b.text).join("");
|
|
50719
|
+
}
|
|
50720
|
+
function createAnthropicTransport(deps = {}) {
|
|
50721
|
+
const doFetch = deps.fetch ?? globalThis.fetch;
|
|
50722
|
+
const url2 = deps.baseUrl ?? ANTHROPIC_MESSAGES_URL;
|
|
50723
|
+
const defaultMaxTokens = deps.defaultMaxTokens ?? DEFAULT_MAX_TOKENS;
|
|
50724
|
+
const usageSink = deps.usageSink ?? noopUsageSink;
|
|
50725
|
+
async function post(call) {
|
|
50726
|
+
const body = toAnthropicBody(call, defaultMaxTokens);
|
|
50727
|
+
let res;
|
|
50728
|
+
try {
|
|
50729
|
+
res = await doFetch(url2, {
|
|
50730
|
+
method: "POST",
|
|
50731
|
+
headers: {
|
|
50732
|
+
"x-api-key": call.apiKey,
|
|
50733
|
+
"anthropic-version": ANTHROPIC_VERSION,
|
|
50734
|
+
"content-type": "application/json"
|
|
50735
|
+
},
|
|
50736
|
+
body: JSON.stringify(body)
|
|
50737
|
+
});
|
|
50738
|
+
} catch (err) {
|
|
50739
|
+
const detail = err instanceof Error ? err.name : "network error";
|
|
50740
|
+
throw new ProviderError(503, `anthropic transport: request failed (${detail})`);
|
|
50741
|
+
}
|
|
50742
|
+
if (!res.ok) {
|
|
50743
|
+
throw new ProviderError(res.status, `anthropic transport: provider returned status ${res.status}`);
|
|
50744
|
+
}
|
|
50745
|
+
const raw2 = await res.text().then((t) => safeJsonParse(t));
|
|
50746
|
+
const parsed = AnthropicMessagesResponseSchema.safeParse(raw2);
|
|
50747
|
+
if (!parsed.success) {
|
|
50748
|
+
throw new ProviderError(502, "anthropic transport: malformed provider response");
|
|
50749
|
+
}
|
|
50750
|
+
const u = parsed.data.usage;
|
|
50751
|
+
const usage = {
|
|
50752
|
+
model: call.target.model,
|
|
50753
|
+
workload: call.request.workload,
|
|
50754
|
+
inputTokens: u.input_tokens,
|
|
50755
|
+
outputTokens: u.output_tokens,
|
|
50756
|
+
cacheReadInputTokens: u.cache_read_input_tokens,
|
|
50757
|
+
cacheCreationInputTokens: u.cache_creation_input_tokens
|
|
50758
|
+
};
|
|
50759
|
+
return { output: joinContentText(parsed.data.content), usage };
|
|
50760
|
+
}
|
|
50761
|
+
return usageReportingTransport(post, usageSink);
|
|
50762
|
+
}
|
|
50763
|
+
|
|
50764
|
+
// dist/src/daemon/runtime/inference/transport-portkey.js
|
|
50765
|
+
var PORTKEY_BASE_URL = "https://api.portkey.ai/v1";
|
|
50766
|
+
var PORTKEY_CHAT_COMPLETIONS_URL = `${PORTKEY_BASE_URL}/chat/completions`;
|
|
50767
|
+
var PORTKEY_RERANK_URL = `${PORTKEY_BASE_URL}/rerank`;
|
|
50768
|
+
var PORTKEY_API_KEY_HEADER = "x-portkey-api-key";
|
|
50769
|
+
var PORTKEY_CONFIG_HEADER = "x-portkey-config";
|
|
50770
|
+
function buildPortkeyHeaders(apiKey, configId) {
|
|
50771
|
+
return {
|
|
50772
|
+
[PORTKEY_API_KEY_HEADER]: apiKey,
|
|
50773
|
+
[PORTKEY_CONFIG_HEADER]: configId,
|
|
50774
|
+
"content-type": "application/json"
|
|
50775
|
+
};
|
|
50776
|
+
}
|
|
50777
|
+
var PORTKEY_DEFAULT_MAX_TOKENS = 4096;
|
|
50778
|
+
var PortkeyChoiceSchema = external_exports.object({
|
|
50779
|
+
message: external_exports.object({ content: external_exports.string().nullable().optional() }).optional()
|
|
50780
|
+
});
|
|
50781
|
+
var PortkeyUsageSchema = external_exports.object({
|
|
50782
|
+
prompt_tokens: external_exports.number().int().nonnegative().catch(0).default(0),
|
|
50783
|
+
completion_tokens: external_exports.number().int().nonnegative().catch(0).default(0),
|
|
50784
|
+
prompt_tokens_details: external_exports.object({ cached_tokens: external_exports.number().int().nonnegative().catch(0).default(0) }).partial().optional()
|
|
50785
|
+
});
|
|
50786
|
+
var ZERO_PORTKEY_USAGE = { prompt_tokens: 0, completion_tokens: 0 };
|
|
50787
|
+
var PortkeyChatResponseSchema = external_exports.object({
|
|
50788
|
+
choices: external_exports.array(PortkeyChoiceSchema).default([]),
|
|
50789
|
+
// As with the Anthropic transport's usage block: `.catch()` so ANY invalid `usage` value
|
|
50790
|
+
// (null, a string, a malformed object) falls back to zero-usage and a VALID completion is
|
|
50791
|
+
// never dropped over its (side-channel) usage block.
|
|
50792
|
+
usage: PortkeyUsageSchema.default(ZERO_PORTKEY_USAGE).catch(ZERO_PORTKEY_USAGE)
|
|
50793
|
+
});
|
|
50794
|
+
function toPortkeyBody(call, defaultMaxTokens) {
|
|
50795
|
+
return {
|
|
50796
|
+
model: call.target.model,
|
|
50797
|
+
max_tokens: call.request.maxTokens ?? defaultMaxTokens,
|
|
50798
|
+
messages: call.request.messages.map((m) => ({ role: m.role, content: m.content }))
|
|
50799
|
+
};
|
|
50800
|
+
}
|
|
50801
|
+
function joinChoiceText(choices) {
|
|
50802
|
+
return choices.map((c) => c.message?.content).filter((t) => typeof t === "string").join("");
|
|
50803
|
+
}
|
|
50804
|
+
function createPortkeyTransport(deps) {
|
|
50805
|
+
const doFetch = deps.fetch ?? globalThis.fetch;
|
|
50806
|
+
const url2 = deps.baseUrl ?? PORTKEY_CHAT_COMPLETIONS_URL;
|
|
50807
|
+
const defaultMaxTokens = deps.defaultMaxTokens ?? PORTKEY_DEFAULT_MAX_TOKENS;
|
|
50808
|
+
const usageSink = deps.usageSink ?? noopUsageSink;
|
|
50809
|
+
const configId = deps.config;
|
|
50810
|
+
const onTransportError = deps.onTransportError;
|
|
50811
|
+
function reportTransportError(statusCode) {
|
|
50812
|
+
if (onTransportError === void 0)
|
|
50813
|
+
return;
|
|
50814
|
+
try {
|
|
50815
|
+
onTransportError(statusCode);
|
|
50816
|
+
} catch {
|
|
50817
|
+
}
|
|
50818
|
+
}
|
|
50819
|
+
async function post(call) {
|
|
50820
|
+
const body = toPortkeyBody(call, defaultMaxTokens);
|
|
50821
|
+
let res;
|
|
50822
|
+
try {
|
|
50823
|
+
res = await doFetch(url2, {
|
|
50824
|
+
method: "POST",
|
|
50825
|
+
headers: buildPortkeyHeaders(call.apiKey, configId),
|
|
50826
|
+
body: JSON.stringify(body)
|
|
50827
|
+
});
|
|
50828
|
+
} catch (err) {
|
|
50829
|
+
reportTransportError(503);
|
|
50830
|
+
const detail = err instanceof Error ? err.name : "network error";
|
|
50831
|
+
throw new ProviderError(503, `portkey transport: request failed (${detail})`);
|
|
50832
|
+
}
|
|
50833
|
+
if (!res.ok) {
|
|
50834
|
+
reportTransportError(res.status);
|
|
50835
|
+
throw new ProviderError(res.status, `portkey transport: gateway returned status ${res.status}`);
|
|
50836
|
+
}
|
|
50837
|
+
const raw2 = await res.text().then((t) => safeJsonParse(t));
|
|
50838
|
+
const parsed = PortkeyChatResponseSchema.safeParse(raw2);
|
|
50839
|
+
if (!parsed.success) {
|
|
50840
|
+
throw new ProviderError(502, "portkey transport: malformed gateway response");
|
|
50841
|
+
}
|
|
50842
|
+
const u = parsed.data.usage;
|
|
50843
|
+
const usage = {
|
|
50844
|
+
model: call.target.model,
|
|
50845
|
+
workload: call.request.workload,
|
|
50846
|
+
inputTokens: u.prompt_tokens,
|
|
50847
|
+
outputTokens: u.completion_tokens,
|
|
50848
|
+
cacheReadInputTokens: u.prompt_tokens_details?.cached_tokens ?? 0,
|
|
50849
|
+
// Portkey's OpenAI-shaped usage has no cache-WRITE field; surface 0 (never fabricate).
|
|
50850
|
+
cacheCreationInputTokens: 0
|
|
50851
|
+
};
|
|
50852
|
+
return { output: joinChoiceText(parsed.data.choices), usage };
|
|
50853
|
+
}
|
|
50854
|
+
return usageReportingTransport(post, usageSink);
|
|
50855
|
+
}
|
|
50406
50856
|
|
|
50407
50857
|
// dist/src/daemon/runtime/inference/model-client-factory.js
|
|
50858
|
+
var PORTKEY_API_KEY_REF = "${PORTKEY_API_KEY}";
|
|
50859
|
+
var PORTKEY_API_KEY_NAME = "PORTKEY_API_KEY";
|
|
50860
|
+
var PORTKEY_ACCOUNT_ID = "portkey-gateway";
|
|
50861
|
+
var PORTKEY_TARGET_ID = "portkey-target";
|
|
50862
|
+
var PORTKEY_POLICY_ID = "portkey-default";
|
|
50863
|
+
var PortkeyUnconfiguredError = class extends Error {
|
|
50864
|
+
constructor() {
|
|
50865
|
+
super("portkey: enabled but PORTKEY_API_KEY is not set (fail-closed; set the key or disable portkey.enabled)");
|
|
50866
|
+
this.name = "PortkeyUnconfiguredError";
|
|
50867
|
+
}
|
|
50868
|
+
};
|
|
50408
50869
|
async function resolveConfig3(source) {
|
|
50409
50870
|
if (typeof source === "string") {
|
|
50410
50871
|
return loadInferenceConfigFromYaml(source);
|
|
@@ -50422,7 +50883,7 @@ function applyProviderModelOverride(config2, override) {
|
|
|
50422
50883
|
workloads: config2.workloads
|
|
50423
50884
|
};
|
|
50424
50885
|
}
|
|
50425
|
-
async function
|
|
50886
|
+
async function buildProviderPathClient(deps) {
|
|
50426
50887
|
let config2;
|
|
50427
50888
|
try {
|
|
50428
50889
|
config2 = await resolveConfig3(deps.config);
|
|
@@ -50443,6 +50904,161 @@ async function buildInferenceModelClient(deps) {
|
|
|
50443
50904
|
});
|
|
50444
50905
|
return new RouterModelClient(router);
|
|
50445
50906
|
}
|
|
50907
|
+
async function buildInferenceModelClient(deps) {
|
|
50908
|
+
const { client } = await buildInferenceModelClientWithStatus(deps);
|
|
50909
|
+
return client;
|
|
50910
|
+
}
|
|
50911
|
+
async function buildInferenceModelClientWithStatus(deps) {
|
|
50912
|
+
const portkey = deps.portkey;
|
|
50913
|
+
if (portkey === void 0 || !portkey.enabled) {
|
|
50914
|
+
return { client: await buildProviderPathClient(deps), portkeyStatus: "off" };
|
|
50915
|
+
}
|
|
50916
|
+
try {
|
|
50917
|
+
const client = await resolvePortkeyClient(deps, portkey);
|
|
50918
|
+
return { client, portkeyStatus: "ok" };
|
|
50919
|
+
} catch (err) {
|
|
50920
|
+
if (err instanceof PortkeyUnconfiguredError) {
|
|
50921
|
+
return { client: noopModelClient, portkeyStatus: "unconfigured" };
|
|
50922
|
+
}
|
|
50923
|
+
return { client: noopModelClient, portkeyStatus: "unconfigured" };
|
|
50924
|
+
}
|
|
50925
|
+
}
|
|
50926
|
+
async function resolvePortkeyClient(deps, portkey) {
|
|
50927
|
+
const names = deps.secretsStore.listSecretNames(deps.scope);
|
|
50928
|
+
if (!names.includes(PORTKEY_API_KEY_NAME)) {
|
|
50929
|
+
throw new PortkeyUnconfiguredError();
|
|
50930
|
+
}
|
|
50931
|
+
const secrets = createSecretResolver(deps.secretsStore, deps.scope);
|
|
50932
|
+
const transport = createPortkeyTransport({
|
|
50933
|
+
config: portkey.config,
|
|
50934
|
+
...deps.usageSink !== void 0 ? { usageSink: deps.usageSink } : {},
|
|
50935
|
+
...deps.onPortkeyUnreachable !== void 0 ? { onTransportError: deps.onPortkeyUnreachable } : {}
|
|
50936
|
+
});
|
|
50937
|
+
const router = createInferenceRouter({
|
|
50938
|
+
config: buildPortkeyConfig(portkey.model),
|
|
50939
|
+
transport,
|
|
50940
|
+
secrets,
|
|
50941
|
+
history: deps.history ?? noopRoutingHistoryStore
|
|
50942
|
+
});
|
|
50943
|
+
const portkeyClient = new RouterModelClient(router);
|
|
50944
|
+
if (!portkey.fallbackToProvider) {
|
|
50945
|
+
return portkeyClient;
|
|
50946
|
+
}
|
|
50947
|
+
const providerClient = await buildProviderPathClient(deps);
|
|
50948
|
+
return new PortkeyFallbackModelClient(portkeyClient, providerClient);
|
|
50949
|
+
}
|
|
50950
|
+
function buildPortkeyConfig(model) {
|
|
50951
|
+
return {
|
|
50952
|
+
accounts: [{ id: PORTKEY_ACCOUNT_ID, provider: "portkey", apiKeyRef: PORTKEY_API_KEY_REF }],
|
|
50953
|
+
targets: [
|
|
50954
|
+
{
|
|
50955
|
+
id: PORTKEY_TARGET_ID,
|
|
50956
|
+
accountRef: PORTKEY_ACCOUNT_ID,
|
|
50957
|
+
model,
|
|
50958
|
+
privacyTier: "public",
|
|
50959
|
+
capabilities: ["chat"],
|
|
50960
|
+
contextWindow: 1e6
|
|
50961
|
+
}
|
|
50962
|
+
],
|
|
50963
|
+
policies: [{ id: PORTKEY_POLICY_ID, mode: "strict", chain: [PORTKEY_TARGET_ID] }],
|
|
50964
|
+
workloads: [
|
|
50965
|
+
{ name: "memory_extraction", policyRef: PORTKEY_POLICY_ID, requiredCapabilities: ["chat"], minPrivacyTier: "public" },
|
|
50966
|
+
{ name: "memory_decision", policyRef: PORTKEY_POLICY_ID, requiredCapabilities: ["chat"], minPrivacyTier: "public" },
|
|
50967
|
+
{ name: "memory_pollinating", policyRef: PORTKEY_POLICY_ID, requiredCapabilities: ["chat"], minPrivacyTier: "public" }
|
|
50968
|
+
]
|
|
50969
|
+
};
|
|
50970
|
+
}
|
|
50971
|
+
var PortkeyFallbackModelClient = class {
|
|
50972
|
+
portkey;
|
|
50973
|
+
provider;
|
|
50974
|
+
constructor(portkey, provider) {
|
|
50975
|
+
this.portkey = portkey;
|
|
50976
|
+
this.provider = provider;
|
|
50977
|
+
}
|
|
50978
|
+
async complete(a, b) {
|
|
50979
|
+
try {
|
|
50980
|
+
return typeof a === "string" ? await this.portkey.complete(a, b) : await this.portkey.complete(a);
|
|
50981
|
+
} catch (err) {
|
|
50982
|
+
void err;
|
|
50983
|
+
return typeof a === "string" ? this.provider.complete(a, b) : this.provider.complete(a);
|
|
50984
|
+
}
|
|
50985
|
+
}
|
|
50986
|
+
};
|
|
50987
|
+
|
|
50988
|
+
// dist/src/daemon/runtime/recall/rerank-portkey.js
|
|
50989
|
+
var RERANK_FAILED = Object.freeze({ ok: false });
|
|
50990
|
+
var RerankResultSchema = external_exports.object({
|
|
50991
|
+
index: external_exports.number().int().nonnegative(),
|
|
50992
|
+
relevance_score: external_exports.number()
|
|
50993
|
+
});
|
|
50994
|
+
var RerankResponseSchema = external_exports.object({
|
|
50995
|
+
results: external_exports.array(RerankResultSchema)
|
|
50996
|
+
});
|
|
50997
|
+
function createPortkeyRerankClient(deps) {
|
|
50998
|
+
const doFetch = deps.fetch ?? globalThis.fetch;
|
|
50999
|
+
const url2 = deps.baseUrl ?? PORTKEY_RERANK_URL;
|
|
51000
|
+
const configId = deps.config;
|
|
51001
|
+
const onTransportError = deps.onTransportError;
|
|
51002
|
+
function reportTransportError(statusCode) {
|
|
51003
|
+
if (onTransportError === void 0)
|
|
51004
|
+
return;
|
|
51005
|
+
try {
|
|
51006
|
+
onTransportError(statusCode);
|
|
51007
|
+
} catch {
|
|
51008
|
+
}
|
|
51009
|
+
}
|
|
51010
|
+
return {
|
|
51011
|
+
async rerank(apiKey, request) {
|
|
51012
|
+
const body = {
|
|
51013
|
+
model: request.model,
|
|
51014
|
+
query: request.query,
|
|
51015
|
+
documents: request.documents,
|
|
51016
|
+
top_n: request.topN
|
|
51017
|
+
};
|
|
51018
|
+
let res;
|
|
51019
|
+
try {
|
|
51020
|
+
res = await doFetch(url2, {
|
|
51021
|
+
method: "POST",
|
|
51022
|
+
// SAME auth pair as the chat transport (c-D-2); the key lives only in the header (c-AC-2).
|
|
51023
|
+
headers: buildPortkeyHeaders(apiKey, configId),
|
|
51024
|
+
body: JSON.stringify(body)
|
|
51025
|
+
});
|
|
51026
|
+
} catch {
|
|
51027
|
+
reportTransportError(503);
|
|
51028
|
+
return RERANK_FAILED;
|
|
51029
|
+
}
|
|
51030
|
+
if (!res.ok) {
|
|
51031
|
+
reportTransportError(res.status);
|
|
51032
|
+
return RERANK_FAILED;
|
|
51033
|
+
}
|
|
51034
|
+
const text = await res.text().catch(() => "");
|
|
51035
|
+
const parsed = RerankResponseSchema.safeParse(safeJsonParse(text));
|
|
51036
|
+
if (!parsed.success) {
|
|
51037
|
+
process.stderr.write("honeycomb: portkey rerank returned an unusable 2xx body; failing soft to RRF order\n");
|
|
51038
|
+
return RERANK_FAILED;
|
|
51039
|
+
}
|
|
51040
|
+
const results = parsed.data.results.filter((r) => r.index < request.documents.length).map((r) => ({ index: r.index, relevanceScore: r.relevance_score }));
|
|
51041
|
+
return { ok: true, results };
|
|
51042
|
+
}
|
|
51043
|
+
};
|
|
51044
|
+
}
|
|
51045
|
+
function buildCohereRerankSeam(deps) {
|
|
51046
|
+
return {
|
|
51047
|
+
async rerank(query, documents, topN) {
|
|
51048
|
+
let apiKey;
|
|
51049
|
+
try {
|
|
51050
|
+
apiKey = await deps.secrets.resolve(deps.apiKeyRef);
|
|
51051
|
+
} catch {
|
|
51052
|
+
return { ok: false };
|
|
51053
|
+
}
|
|
51054
|
+
try {
|
|
51055
|
+
return await deps.client.rerank(apiKey, { model: deps.model, query, documents, topN });
|
|
51056
|
+
} catch {
|
|
51057
|
+
return RERANK_FAILED;
|
|
51058
|
+
}
|
|
51059
|
+
}
|
|
51060
|
+
};
|
|
51061
|
+
}
|
|
50446
51062
|
|
|
50447
51063
|
// dist/src/daemon/runtime/services/poll-backoff.js
|
|
50448
51064
|
var DEFAULT_POLL_BACKOFF_FLOOR_MS = 1e3;
|
|
@@ -52394,7 +53010,7 @@ function sanitizeSegment4(name) {
|
|
|
52394
53010
|
// dist/src/daemon/runtime/skillify/watermark.js
|
|
52395
53011
|
import { mkdirSync as mkdirSync19, readFileSync as readFileSync21, writeFileSync as writeFileSync16 } from "node:fs";
|
|
52396
53012
|
import { homedir as homedir23 } from "node:os";
|
|
52397
|
-
import { dirname as
|
|
53013
|
+
import { dirname as dirname14, join as join30 } from "node:path";
|
|
52398
53014
|
function defaultWatermarkBaseDir() {
|
|
52399
53015
|
return join30(homedir23(), ".honeycomb", "state", "skillify");
|
|
52400
53016
|
}
|
|
@@ -52420,7 +53036,7 @@ function createWatermarkStore(baseDir = defaultWatermarkBaseDir()) {
|
|
|
52420
53036
|
const next = current === null ? oldest : earlier(current, oldest);
|
|
52421
53037
|
const file2 = { watermark: next, updatedAt: (/* @__PURE__ */ new Date()).toISOString() };
|
|
52422
53038
|
const path4 = fileFor(projectKey);
|
|
52423
|
-
mkdirSync19(
|
|
53039
|
+
mkdirSync19(dirname14(path4), { recursive: true });
|
|
52424
53040
|
writeFileSync16(path4, JSON.stringify(file2, null, 2), "utf-8");
|
|
52425
53041
|
return next;
|
|
52426
53042
|
}
|
|
@@ -53181,6 +53797,7 @@ var AGENT_CONFIG_FILE_NAME = "agent.yaml";
|
|
|
53181
53797
|
var LOCK_FILE_NAME = "daemon.lock";
|
|
53182
53798
|
var PID_FILE_NAME = "daemon.pid";
|
|
53183
53799
|
var DEFAULT_HEALTH_PROBE_INTERVAL_MS = 15e3;
|
|
53800
|
+
var DEFAULT_GRAPH_BUILD_INTERVAL_MS = 60 * 60 * 1e3;
|
|
53184
53801
|
var defaultSeamFns = {
|
|
53185
53802
|
attachHooks: attachHooksHandlers,
|
|
53186
53803
|
mountDashboard: mountDashboardApi,
|
|
@@ -53258,7 +53875,7 @@ function readPidFile(path4) {
|
|
|
53258
53875
|
function releaseSingleInstanceLock(runtimeDir) {
|
|
53259
53876
|
for (const name of [LOCK_FILE_NAME, PID_FILE_NAME]) {
|
|
53260
53877
|
try {
|
|
53261
|
-
|
|
53878
|
+
rmSync10(join32(runtimeDir, name), { force: true });
|
|
53262
53879
|
} catch {
|
|
53263
53880
|
}
|
|
53264
53881
|
}
|
|
@@ -53281,7 +53898,7 @@ function authForMode(mode, storage, scope) {
|
|
|
53281
53898
|
}
|
|
53282
53899
|
return { authenticator: composeAuthenticator(storage, scope), policy: defaultDenyPolicy };
|
|
53283
53900
|
}
|
|
53284
|
-
function assembleSeams(daemon, storage, defaultScope, orgName, embed, healthDetail, workspaceDir, installedHarnesses, logStore, seams = defaultSeamFns, vault) {
|
|
53901
|
+
function assembleSeams(daemon, storage, defaultScope, orgName, embed, healthDetail, workspaceDir, installedHarnesses, logStore, seams = defaultSeamFns, vault, rerankerDeps) {
|
|
53285
53902
|
const captureHandler = seams.attachHooks(daemon, {
|
|
53286
53903
|
storage,
|
|
53287
53904
|
queue: daemon.services.queue,
|
|
@@ -53326,7 +53943,12 @@ function assembleSeams(daemon, storage, defaultScope, orgName, embed, healthDeta
|
|
|
53326
53943
|
embed: embed.client,
|
|
53327
53944
|
logger: daemon.logger,
|
|
53328
53945
|
conflictSuppression,
|
|
53329
|
-
...vault !== void 0 ? { vault } : {}
|
|
53946
|
+
...vault !== void 0 ? { vault } : {},
|
|
53947
|
+
// PRD-063c: the operator-selected reranker config + the late-bound Cohere-via-Portkey seam.
|
|
53948
|
+
// The `cohere` strategy only does anything when BOTH the strategy is `cohere` (env) AND the
|
|
53949
|
+
// gateway is ON (the seam's inner transport is wired in `start()`); otherwise RRF / local
|
|
53950
|
+
// cosine, byte-identical to today (c-AC-4). Absent rerankerDeps (a unit mount) → engine default.
|
|
53951
|
+
...rerankerDeps !== void 0 ? { reranker: rerankerDeps.reranker, cohereRerank: rerankerDeps.cohereRerank } : {}
|
|
53330
53952
|
});
|
|
53331
53953
|
if (seams.mountConflicts !== void 0) {
|
|
53332
53954
|
seams.mountConflicts(daemon, { storage, defaultScope });
|
|
@@ -53410,7 +54032,7 @@ function assembleSeams(daemon, storage, defaultScope, orgName, embed, healthDeta
|
|
|
53410
54032
|
return captureHandler;
|
|
53411
54033
|
}
|
|
53412
54034
|
function resolveProductDataDeps(storage, defaultScope, queue, embed, mode) {
|
|
53413
|
-
const baseDir =
|
|
54035
|
+
const baseDir = resolveWorkspaceBaseDir();
|
|
53414
54036
|
const secrets = {
|
|
53415
54037
|
store: new SecretsStore({ baseDir, machineKey: createMachineKeyProvider() }),
|
|
53416
54038
|
// PRD-022 local-mode default: the dashboard's `GET /api/secrets` (names-only) carries no
|
|
@@ -53434,8 +54056,35 @@ function resolveProductDataDeps(storage, defaultScope, queue, embed, mode) {
|
|
|
53434
54056
|
defaultScope
|
|
53435
54057
|
};
|
|
53436
54058
|
}
|
|
54059
|
+
var workspaceBaseDirMemo;
|
|
53437
54060
|
function resolveWorkspaceBaseDir() {
|
|
53438
|
-
|
|
54061
|
+
if (workspaceBaseDirMemo !== void 0)
|
|
54062
|
+
return workspaceBaseDirMemo;
|
|
54063
|
+
const fromEnv = process.env.HONEYCOMB_WORKSPACE;
|
|
54064
|
+
const candidate = fromEnv !== void 0 && fromEnv.length > 0 ? fromEnv : process.cwd();
|
|
54065
|
+
if (isWritableDir(candidate)) {
|
|
54066
|
+
workspaceBaseDirMemo = candidate;
|
|
54067
|
+
return candidate;
|
|
54068
|
+
}
|
|
54069
|
+
const fallback = join32(homedir25(), ".honeycomb");
|
|
54070
|
+
process.stderr.write(`honeycomb: workspace "${candidate}" is not writable; using "${fallback}" for filesystem state (secrets, logs, agent.yaml)
|
|
54071
|
+
`);
|
|
54072
|
+
try {
|
|
54073
|
+
mkdirSync20(fallback, { recursive: true, mode: DIR_MODE });
|
|
54074
|
+
} catch {
|
|
54075
|
+
}
|
|
54076
|
+
workspaceBaseDirMemo = fallback;
|
|
54077
|
+
return fallback;
|
|
54078
|
+
}
|
|
54079
|
+
function isWritableDir(dir) {
|
|
54080
|
+
try {
|
|
54081
|
+
mkdirSync20(dir, { recursive: true });
|
|
54082
|
+
const probe = mkdtempSync(join32(dir, ".honeycomb-write-test-"));
|
|
54083
|
+
rmSync10(probe, { recursive: true, force: true });
|
|
54084
|
+
return true;
|
|
54085
|
+
} catch {
|
|
54086
|
+
return false;
|
|
54087
|
+
}
|
|
53439
54088
|
}
|
|
53440
54089
|
function resolveAgentConfigPath(options) {
|
|
53441
54090
|
return options.agentConfigPath ?? join32(resolveWorkspaceBaseDir(), AGENT_CONFIG_FILE_NAME);
|
|
@@ -53446,6 +54095,9 @@ function secretScopeFromQueryScope(scope) {
|
|
|
53446
54095
|
var VAULT_PROVIDER_KEY = "activeProvider";
|
|
53447
54096
|
var VAULT_MODEL_KEY = "activeModel";
|
|
53448
54097
|
var VAULT_POLLINATING_ENABLED_KEY = "pollinating.enabled";
|
|
54098
|
+
var VAULT_PORTKEY_ENABLED_KEY = "portkey.enabled";
|
|
54099
|
+
var VAULT_PORTKEY_CONFIG_KEY = "portkey.config";
|
|
54100
|
+
var VAULT_PORTKEY_FALLBACK_KEY = "portkey.fallbackToProvider";
|
|
53449
54101
|
function catalogTrustedTableProbe() {
|
|
53450
54102
|
const names = CATALOG.map((t) => t.name);
|
|
53451
54103
|
return { tables: () => Promise.resolve(names) };
|
|
@@ -53476,6 +54128,41 @@ async function readProviderModelOverride(vault, scope) {
|
|
|
53476
54128
|
return void 0;
|
|
53477
54129
|
}
|
|
53478
54130
|
}
|
|
54131
|
+
async function readPortkeySelection(vault, scope) {
|
|
54132
|
+
if (vault === void 0)
|
|
54133
|
+
return void 0;
|
|
54134
|
+
try {
|
|
54135
|
+
const enabledRes = await vault.getSetting(VAULT_PORTKEY_ENABLED_KEY, scope);
|
|
54136
|
+
const enabled = enabledRes.ok && coerceSettingBool(enabledRes.value);
|
|
54137
|
+
if (!enabled)
|
|
54138
|
+
return void 0;
|
|
54139
|
+
const configRes = await vault.getSetting(VAULT_PORTKEY_CONFIG_KEY, scope);
|
|
54140
|
+
const config2 = configRes.ok ? String(configRes.value) : "";
|
|
54141
|
+
if (config2.length === 0)
|
|
54142
|
+
return void 0;
|
|
54143
|
+
const modelRes = await vault.getSetting(VAULT_MODEL_KEY, scope);
|
|
54144
|
+
const model = modelRes.ok ? String(modelRes.value) : "";
|
|
54145
|
+
const fallbackRes = await vault.getSetting(VAULT_PORTKEY_FALLBACK_KEY, scope);
|
|
54146
|
+
const fallbackToProvider = fallbackRes.ok && coerceSettingBool(fallbackRes.value);
|
|
54147
|
+
return { enabled: true, config: config2, model, fallbackToProvider };
|
|
54148
|
+
} catch {
|
|
54149
|
+
return void 0;
|
|
54150
|
+
}
|
|
54151
|
+
}
|
|
54152
|
+
async function resolvePortkeyAssemblyStatus(selection, scope) {
|
|
54153
|
+
if (selection === void 0 || !selection.enabled)
|
|
54154
|
+
return "off";
|
|
54155
|
+
try {
|
|
54156
|
+
const secretsStore = new SecretsStore({
|
|
54157
|
+
baseDir: resolveWorkspaceBaseDir(),
|
|
54158
|
+
machineKey: createMachineKeyProvider()
|
|
54159
|
+
});
|
|
54160
|
+
const names = secretsStore.listSecretNames(secretScopeFromQueryScope(scope));
|
|
54161
|
+
return names.includes(PORTKEY_API_KEY_NAME) ? "ok" : "unconfigured";
|
|
54162
|
+
} catch {
|
|
54163
|
+
return "unconfigured";
|
|
54164
|
+
}
|
|
54165
|
+
}
|
|
53479
54166
|
async function readVaultPollinatingEnabled(vault, scope) {
|
|
53480
54167
|
if (vault === void 0)
|
|
53481
54168
|
return { decidedByVault: false, enabled: false };
|
|
@@ -53489,6 +54176,17 @@ async function readVaultPollinatingEnabled(vault, scope) {
|
|
|
53489
54176
|
return { decidedByVault: false, enabled: false };
|
|
53490
54177
|
}
|
|
53491
54178
|
}
|
|
54179
|
+
async function readBootEmbeddingsEnabled(vault, scope) {
|
|
54180
|
+
if (vault !== void 0) {
|
|
54181
|
+
try {
|
|
54182
|
+
const res = await vault.getSetting(EMBEDDINGS_ENABLED_KEY, scope);
|
|
54183
|
+
if (res.ok)
|
|
54184
|
+
return coerceSettingBool(res.value);
|
|
54185
|
+
} catch {
|
|
54186
|
+
}
|
|
54187
|
+
}
|
|
54188
|
+
return resolveEmbedClientOptions().enabled;
|
|
54189
|
+
}
|
|
53492
54190
|
function coerceSettingBool(value) {
|
|
53493
54191
|
if (typeof value === "boolean")
|
|
53494
54192
|
return value;
|
|
@@ -53498,7 +54196,7 @@ function coerceSettingBool(value) {
|
|
|
53498
54196
|
return value === "true" || value === "1";
|
|
53499
54197
|
return false;
|
|
53500
54198
|
}
|
|
53501
|
-
async function buildGatedPollinatingWorker(options, storage, scope, queue, vault, backoff) {
|
|
54199
|
+
async function buildGatedPollinatingWorker(options, storage, scope, queue, vault, backoff, portkeyDeps) {
|
|
53502
54200
|
let config2;
|
|
53503
54201
|
try {
|
|
53504
54202
|
config2 = resolvePollinatingConfig(options.pollinatingConfigProvider);
|
|
@@ -53522,7 +54220,9 @@ async function buildGatedPollinatingWorker(options, storage, scope, queue, vault
|
|
|
53522
54220
|
scope: secretScopeFromQueryScope(scope),
|
|
53523
54221
|
secretsStore,
|
|
53524
54222
|
config: resolveAgentConfigPath(options),
|
|
53525
|
-
...providerModelOverride !== void 0 ? { providerModelOverride } : {}
|
|
54223
|
+
...providerModelOverride !== void 0 ? { providerModelOverride } : {},
|
|
54224
|
+
...portkeyDeps?.selection !== void 0 ? { portkey: portkeyDeps.selection } : {},
|
|
54225
|
+
...portkeyDeps !== void 0 ? { onPortkeyUnreachable: portkeyDeps.onUnreachable } : {}
|
|
53526
54226
|
});
|
|
53527
54227
|
const trigger = createPollinatingTrigger({ storage, scope, config: config2, enqueuer: queue });
|
|
53528
54228
|
return createPollinatingWorker({ queue, storage, scope, config: config2, model, trigger, backoff });
|
|
@@ -53546,7 +54246,7 @@ function makePipelineEntryEnqueuer(queue) {
|
|
|
53546
54246
|
});
|
|
53547
54247
|
};
|
|
53548
54248
|
}
|
|
53549
|
-
async function buildPipelineWorker(options, storage, scope, queue, embed, backoff) {
|
|
54249
|
+
async function buildPipelineWorker(options, storage, scope, queue, embed, backoff, portkeyDeps) {
|
|
53550
54250
|
let config2;
|
|
53551
54251
|
try {
|
|
53552
54252
|
config2 = resolvePipelineConfig();
|
|
@@ -53562,7 +54262,9 @@ async function buildPipelineWorker(options, storage, scope, queue, embed, backof
|
|
|
53562
54262
|
model = await buildInferenceModelClient({
|
|
53563
54263
|
scope: secretScopeFromQueryScope(scope),
|
|
53564
54264
|
secretsStore,
|
|
53565
|
-
config: resolveAgentConfigPath(options)
|
|
54265
|
+
config: resolveAgentConfigPath(options),
|
|
54266
|
+
...portkeyDeps?.selection !== void 0 ? { portkey: portkeyDeps.selection } : {},
|
|
54267
|
+
...portkeyDeps !== void 0 ? { onPortkeyUnreachable: portkeyDeps.onUnreachable } : {}
|
|
53566
54268
|
});
|
|
53567
54269
|
} catch {
|
|
53568
54270
|
model = noopModelClient;
|
|
@@ -53597,6 +54299,7 @@ function assembleDaemon(options = {}) {
|
|
|
53597
54299
|
const tenancy = resolveDaemonTenancy(provider);
|
|
53598
54300
|
const scope = tenancy.scope;
|
|
53599
54301
|
const daemonOrgName = tenancy.orgName;
|
|
54302
|
+
const vault = options.vault ?? (options.storage === void 0 ? buildVaultStore() : void 0);
|
|
53600
54303
|
const services = {
|
|
53601
54304
|
queue: createJobQueueService({ storage, scope }),
|
|
53602
54305
|
watcher: createFileWatcherService({
|
|
@@ -53612,10 +54315,34 @@ function assembleDaemon(options = {}) {
|
|
|
53612
54315
|
// fake supervisor so the hermetic assembly never spawns a real process.
|
|
53613
54316
|
embed: options.embedSupervisor ?? createEmbedSupervisor()
|
|
53614
54317
|
};
|
|
54318
|
+
const embedSupervisor = services.embed;
|
|
54319
|
+
if (embedSupervisor !== void 0 && vault !== void 0) {
|
|
54320
|
+
void readBootEmbeddingsEnabled(vault, secretScopeFromQueryScope(scope)).then(async (enabled) => {
|
|
54321
|
+
if (enabled !== !embedSupervisor.disabled)
|
|
54322
|
+
await embedSupervisor.setEnabled(enabled);
|
|
54323
|
+
}).catch((err) => {
|
|
54324
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
54325
|
+
process.stderr.write(`honeycomb: embeddings boot reconciliation failed (non-fatal): ${reason}
|
|
54326
|
+
`);
|
|
54327
|
+
});
|
|
54328
|
+
}
|
|
53615
54329
|
let healthBit = "ok";
|
|
53616
54330
|
const pipelineProbe = () => healthBit;
|
|
53617
|
-
const
|
|
53618
|
-
|
|
54331
|
+
const embeddingsReason = () => options.embeddingsEnabled ?? (options.embed !== void 0 ? false : embedSupervisor !== void 0 ? !embedSupervisor.disabled : resolveEmbedClientOptions().enabled);
|
|
54332
|
+
let portkeyHealth = "off";
|
|
54333
|
+
const recordPortkeyUnreachable = (_statusCode) => {
|
|
54334
|
+
portkeyHealth = "unreachable";
|
|
54335
|
+
};
|
|
54336
|
+
const healthDetail = () => buildHealthDetail({ status: healthBit, embeddingsEnabled: embeddingsReason(), portkey: portkeyHealth });
|
|
54337
|
+
let cohereRerankInner;
|
|
54338
|
+
const cohereRerankSeam = {
|
|
54339
|
+
rerank(query, documents, topN) {
|
|
54340
|
+
const inner = cohereRerankInner;
|
|
54341
|
+
if (inner === void 0)
|
|
54342
|
+
return Promise.resolve({ ok: false });
|
|
54343
|
+
return inner.rerank(query, documents, topN);
|
|
54344
|
+
}
|
|
54345
|
+
};
|
|
53619
54346
|
const { authenticator, policy } = authForMode(config2.mode, storage, scope);
|
|
53620
54347
|
const createOptions = {
|
|
53621
54348
|
config: config2,
|
|
@@ -53630,8 +54357,16 @@ function assembleDaemon(options = {}) {
|
|
|
53630
54357
|
const daemon = createDaemon(createOptions);
|
|
53631
54358
|
const embed = options.embed ?? createEmbedAttachment({ storage });
|
|
53632
54359
|
const installedHarnesses = options.installedHarnesses ?? (options.harnessTargets !== void 0 && options.harnessTargets.length > 0 ? new Set(options.harnessTargets.map((t) => t.name)) : options.storage === void 0 ? detectInstalledHarnesses() : /* @__PURE__ */ new Set());
|
|
53633
|
-
|
|
53634
|
-
|
|
54360
|
+
let rerankerMountDeps;
|
|
54361
|
+
try {
|
|
54362
|
+
rerankerMountDeps = { reranker: resolveRecallConfig().reranker, cohereRerank: cohereRerankSeam };
|
|
54363
|
+
} catch {
|
|
54364
|
+
rerankerMountDeps = {
|
|
54365
|
+
reranker: RecallConfigSchema.parse({}).reranker,
|
|
54366
|
+
cohereRerank: cohereRerankSeam
|
|
54367
|
+
};
|
|
54368
|
+
}
|
|
54369
|
+
const captureHandler = assembleSeams(daemon, storage, scope, daemonOrgName, embed, healthDetail, options.workspaceDir ?? process.cwd(), installedHarnesses, logStore, options.seams ?? defaultSeamFns, vault, rerankerMountDeps);
|
|
53635
54370
|
if (vault !== void 0 && vault instanceof VaultStore) {
|
|
53636
54371
|
try {
|
|
53637
54372
|
mountSettingsApi(daemon, { store: vault, scope: localDefaultScopeResolver(daemon.config.mode, scope) });
|
|
@@ -53646,6 +54381,17 @@ function assembleDaemon(options = {}) {
|
|
|
53646
54381
|
} catch (err) {
|
|
53647
54382
|
const reason = err instanceof Error ? err.message : String(err);
|
|
53648
54383
|
process.stderr.write(`honeycomb: auth status API mount failed (non-fatal): ${reason}
|
|
54384
|
+
`);
|
|
54385
|
+
}
|
|
54386
|
+
try {
|
|
54387
|
+
mountActionsApi(daemon, {
|
|
54388
|
+
embed: daemon.services.embed,
|
|
54389
|
+
defaultScope: scope,
|
|
54390
|
+
...vault instanceof VaultStore ? { store: vault } : {}
|
|
54391
|
+
});
|
|
54392
|
+
} catch (err) {
|
|
54393
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
54394
|
+
process.stderr.write(`honeycomb: actions API mount failed (non-fatal): ${reason}
|
|
53649
54395
|
`);
|
|
53650
54396
|
}
|
|
53651
54397
|
try {
|
|
@@ -53696,6 +54442,27 @@ function assembleDaemon(options = {}) {
|
|
|
53696
54442
|
healthBit = "degraded";
|
|
53697
54443
|
}
|
|
53698
54444
|
}
|
|
54445
|
+
const autoBuildGraph = options.storage === void 0 && config2.mode === "local";
|
|
54446
|
+
let graphBuildTimer = null;
|
|
54447
|
+
let graphBuildInFlight = false;
|
|
54448
|
+
async function rebuildCodebaseGraph() {
|
|
54449
|
+
if (graphBuildInFlight)
|
|
54450
|
+
return;
|
|
54451
|
+
graphBuildInFlight = true;
|
|
54452
|
+
try {
|
|
54453
|
+
await buildCodebaseGraphSnapshot(scope, {
|
|
54454
|
+
storage,
|
|
54455
|
+
defaultScope: scope,
|
|
54456
|
+
workspaceDir: options.workspaceDir ?? process.cwd()
|
|
54457
|
+
});
|
|
54458
|
+
} catch (err) {
|
|
54459
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
54460
|
+
process.stderr.write(`honeycomb: codebase graph auto-build failed (non-fatal): ${reason}
|
|
54461
|
+
`);
|
|
54462
|
+
} finally {
|
|
54463
|
+
graphBuildInFlight = false;
|
|
54464
|
+
}
|
|
54465
|
+
}
|
|
53699
54466
|
let started = false;
|
|
53700
54467
|
let locked = false;
|
|
53701
54468
|
let pollinatingWorker = null;
|
|
@@ -53720,6 +54487,15 @@ function assembleDaemon(options = {}) {
|
|
|
53720
54487
|
if (typeof probeTimer.unref === "function") {
|
|
53721
54488
|
probeTimer.unref();
|
|
53722
54489
|
}
|
|
54490
|
+
if (autoBuildGraph) {
|
|
54491
|
+
void rebuildCodebaseGraph();
|
|
54492
|
+
graphBuildTimer = setInterval(() => {
|
|
54493
|
+
void rebuildCodebaseGraph();
|
|
54494
|
+
}, DEFAULT_GRAPH_BUILD_INTERVAL_MS);
|
|
54495
|
+
if (typeof graphBuildTimer.unref === "function") {
|
|
54496
|
+
graphBuildTimer.unref();
|
|
54497
|
+
}
|
|
54498
|
+
}
|
|
53723
54499
|
await daemon.startServices();
|
|
53724
54500
|
let pollBackoff;
|
|
53725
54501
|
try {
|
|
@@ -53733,6 +54509,33 @@ function assembleDaemon(options = {}) {
|
|
|
53733
54509
|
} catch {
|
|
53734
54510
|
consolidatePoll = false;
|
|
53735
54511
|
}
|
|
54512
|
+
let portkeyWorkerDeps = { onUnreachable: recordPortkeyUnreachable };
|
|
54513
|
+
try {
|
|
54514
|
+
const portkeySelection = await readPortkeySelection(vault, secretScopeFromQueryScope(scope));
|
|
54515
|
+
portkeyHealth = await resolvePortkeyAssemblyStatus(portkeySelection, scope);
|
|
54516
|
+
portkeyWorkerDeps = {
|
|
54517
|
+
...portkeySelection !== void 0 ? { selection: portkeySelection } : {},
|
|
54518
|
+
onUnreachable: recordPortkeyUnreachable
|
|
54519
|
+
};
|
|
54520
|
+
if (portkeySelection !== void 0) {
|
|
54521
|
+
const rerankSecrets = createSecretResolver(new SecretsStore({ baseDir: resolveWorkspaceBaseDir(), machineKey: createMachineKeyProvider() }), secretScopeFromQueryScope(scope));
|
|
54522
|
+
const rerankClient = createPortkeyRerankClient({
|
|
54523
|
+
config: portkeySelection.config,
|
|
54524
|
+
onTransportError: recordPortkeyUnreachable
|
|
54525
|
+
});
|
|
54526
|
+
cohereRerankInner = buildCohereRerankSeam({
|
|
54527
|
+
client: rerankClient,
|
|
54528
|
+
secrets: rerankSecrets,
|
|
54529
|
+
apiKeyRef: PORTKEY_API_KEY_REF,
|
|
54530
|
+
model: rerankerMountDeps.reranker.cohereModel
|
|
54531
|
+
});
|
|
54532
|
+
} else {
|
|
54533
|
+
cohereRerankInner = void 0;
|
|
54534
|
+
}
|
|
54535
|
+
} catch {
|
|
54536
|
+
portkeyHealth = "off";
|
|
54537
|
+
cohereRerankInner = void 0;
|
|
54538
|
+
}
|
|
53736
54539
|
try {
|
|
53737
54540
|
summaryWorker = buildSummaryWorker(storage, scope, daemon.services.queue, embed);
|
|
53738
54541
|
summaryWorker.start();
|
|
@@ -53743,7 +54546,7 @@ function assembleDaemon(options = {}) {
|
|
|
53743
54546
|
summaryWorker = null;
|
|
53744
54547
|
}
|
|
53745
54548
|
try {
|
|
53746
|
-
pipelineWorker = await buildPipelineWorker(options, storage, scope, daemon.services.queue, embed, pollBackoff);
|
|
54549
|
+
pipelineWorker = await buildPipelineWorker(options, storage, scope, daemon.services.queue, embed, pollBackoff, portkeyWorkerDeps);
|
|
53747
54550
|
if (!consolidatePoll)
|
|
53748
54551
|
pipelineWorker.start();
|
|
53749
54552
|
} catch (err) {
|
|
@@ -53775,7 +54578,7 @@ function assembleDaemon(options = {}) {
|
|
|
53775
54578
|
}
|
|
53776
54579
|
}
|
|
53777
54580
|
try {
|
|
53778
|
-
pollinatingWorker = await buildGatedPollinatingWorker(options, storage, scope, daemon.services.queue, vault, pollBackoff);
|
|
54581
|
+
pollinatingWorker = await buildGatedPollinatingWorker(options, storage, scope, daemon.services.queue, vault, pollBackoff, portkeyWorkerDeps);
|
|
53779
54582
|
const pollinatingInjected = options.pollinatingWorker !== void 0;
|
|
53780
54583
|
if (consolidatePoll && !pollinatingInjected) {
|
|
53781
54584
|
const participants = [pipelineWorker, pollinatingWorker].filter((p) => p !== null);
|
|
@@ -53830,6 +54633,10 @@ function assembleDaemon(options = {}) {
|
|
|
53830
54633
|
clearInterval(probeTimer);
|
|
53831
54634
|
probeTimer = null;
|
|
53832
54635
|
}
|
|
54636
|
+
if (graphBuildTimer !== null) {
|
|
54637
|
+
clearInterval(graphBuildTimer);
|
|
54638
|
+
graphBuildTimer = null;
|
|
54639
|
+
}
|
|
53833
54640
|
if (started) {
|
|
53834
54641
|
await daemon.stopServices();
|
|
53835
54642
|
started = false;
|